Summary: This allows opening the Chrome debugger on OS X, Linux, and Windows, and succeeds the previous PR which used [browser-launcher2](https://github.com/benderjs/browser-launcher2) and included a `--dangerouslyDisableChromeDebuggerWebSecurity` option: https://github.com/facebook/react-native/pull/2406

[opn](https://github.com/sindresorhus/opn) is cross-platform and much simpler than browser-launcher2 (since we don't have to manage the opened Chrome instance; the OS will just use the default instance).
Closes https://github.com/facebook/react-native/pull/3394

Reviewed By: mkonicek

Differential Revision: D2550996

Pulled By: frantic

fb-gh-sync-id: fa4cbe55542562f30f77e0a6ab4bc53980ee13aa
This commit is contained in:
Spencer Elliott 2015-10-23 11:28:49 -07:00 committed by facebook-github-bot-6
parent f0cf0b0288
commit c1faabcdf6
5 changed files with 44 additions and 67 deletions

View File

@ -10,9 +10,21 @@
var execFile = require('child_process').execFile;
var fs = require('fs');
var opn = require('opn');
var path = require('path');
module.exports = function(options) {
function getChromeAppName() {
switch (process.platform) {
case 'darwin':
return 'google chrome';
case 'win32':
return 'chrome';
default:
return 'google-chrome';
}
}
module.exports = function(options, isDebuggerConnected) {
return function(req, res, next) {
if (req.url === '/debugger-ui') {
var debuggerPath = path.join(__dirname, 'debugger.html');
@ -29,19 +41,18 @@ module.exports = function(options) {
'If you still need this, please let us know.'
);
} else if (req.url === '/launch-chrome-devtools') {
if (isDebuggerConnected()) {
// Dev tools are already open; no need to open another session
res.end('OK');
return;
}
var debuggerURL = 'http://localhost:' + options.port + '/debugger-ui';
var script = 'launchChromeDevTools.applescript';
console.log('Launching Dev Tools...');
execFile(
path.join(__dirname, script), [debuggerURL],
function(err, stdout, stderr) {
if (err) {
console.log('Failed to run ' + script, err);
}
console.log(stdout);
console.warn(stderr);
opn(debuggerURL, {app: [getChromeAppName()]}, function(err) {
if (err) {
console.error('Google Chrome exited with error:', err);
}
);
});
res.end('OK');
} else {
next();

View File

@ -1,47 +0,0 @@
#!/usr/bin/env osascript
-- Copyright (c) 2015-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is licensed under the BSD-style license found in the
-- LICENSE file in the root directory of this source tree. An additional grant
-- of patent rights can be found in the PATENTS file in the same directory.
on run argv
set theURL to item 1 of argv
tell application "Chrome"
if (count every window) = 0 then
make new window
end if
-- Find a tab currently running the debugger
set found to false
set theTabIndex to -1
repeat with theWindow in every window
set theTabIndex to 0
repeat with theTab in every tab of theWindow
set theTabIndex to theTabIndex + 1
if theTab's URL is theURL then
set found to true
exit repeat
end if
end repeat
if found then
exit repeat
end if
end repeat
if found then
set index of theWindow to 1
set theWindow's active tab index to theTabIndex
else
tell window 1
activate
make new tab with properties {URL:theURL}
end tell
end if
end tell
end run

View File

@ -22,7 +22,7 @@ function attachToServer(server, path) {
try {
cn.send(JSON.stringify(message));
} catch(e) {
console.warn('WARN: ' + e.message);
// Sometimes this call throws 'not opened'
}
});
}
@ -57,7 +57,14 @@ function attachToServer(server, path) {
});
});
return wss;
return {
server: wss,
isChromeConnected: () =>
clients
.map(ws => ws.upgradeReq.headers['user-agent'])
.filter(Boolean)
.some(userAgent => userAgent.includes('Chrome'))
};
}
module.exports = {

View File

@ -20,11 +20,13 @@ const path = require('path');
const ReactPackager = require('../../../packager/react-packager');
const statusPageMiddleware = require('../../../packager/statusPageMiddleware.js');
const systraceProfileMiddleware = require('../../../packager/systraceProfileMiddleware.js');
const webSocketProxy = require('../../../packager/webSocketProxy.js');
function runServer(args, config, readyCallback) {
var wsProxy = null;
const app = connect()
.use(loadRawBodyMiddleware)
.use(getDevToolsMiddleware(args))
.use(getDevToolsMiddleware(args, () => wsProxy && wsProxy.isChromeConnected()))
.use(openStackFrameInEditorMiddleware)
.use(statusPageMiddleware)
.use(systraceProfileMiddleware)
@ -39,7 +41,15 @@ function runServer(args, config, readyCallback) {
.use(connect.compress())
.use(connect.errorHandler());
return http.createServer(app).listen(args.port, '::', readyCallback);
const serverInstance = http.createServer(app).listen(
args.port,
'::',
function() {
wsProxy = webSocketProxy.attachToServer(serverInstance, '/debugger-proxy');
webSocketProxy.attachToServer(serverInstance, '/devtools');
readyCallback();
}
);
}
function getAppMiddleware(args, config) {

View File

@ -15,7 +15,6 @@ const parseCommandLine = require('../../../packager/parseCommandLine');
const path = require('path');
const Promise = require('promise');
const runServer = require('./runServer');
const webSocketProxy = require('../../../packager/webSocketProxy.js');
/**
* Starts the React Native Packager Server.
@ -138,12 +137,9 @@ function _server(argv, config, resolve, reject) {
}
function startServer(args, config) {
const serverInstance = runServer(args, config, () =>
runServer(args, config, () =>
console.log('\nReact packager ready.\n')
);
webSocketProxy.attachToServer(serverInstance, '/debugger-proxy');
webSocketProxy.attachToServer(serverInstance, '/devtools');
}
function argToArray(arg) {