Files
create-react-app/packages/react-dev-utils/openBrowser.js
Gabriel Aumala 8f028ae4b5 Support node scripts in BROWSER (#1590)
* Support node scripts in BROWSER

Modify OpenBrowser.js to run node scripts specified with the BROWSER environment
variable . If the value of the BROWSER environment variable ends with '.js' a
child process is spawned to execute the script with node.js. Any
arguments passed to npm start are also passed to this script, as well as
the url where the app is served.
The command executed in the child process is:

node <pathToScript> [OPTIONS] <url>

Update User Guide.

* Tweak code style

* Pin dep

* Comment out 0.10 docs
2017-05-16 00:25:04 +01:00

128 lines
3.7 KiB
JavaScript

/**
* 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.
*/
'use strict';
var chalk = require('chalk');
var execSync = require('child_process').execSync;
var spawn = require('cross-spawn');
var opn = require('opn');
// https://github.com/sindresorhus/opn#app
var OSX_CHROME = 'google chrome';
const Actions = Object.freeze({
NONE: 0,
BROWSER: 1,
SCRIPT: 2,
});
function getBrowserEnv() {
// Attempt to honor this environment variable.
// It is specific to the operating system.
// See https://github.com/sindresorhus/opn#app for documentation.
const value = process.env.BROWSER;
let action;
if (!value) {
// Default.
action = Actions.BROWSER;
} else if (value.toLowerCase().endsWith('.js')) {
action = Actions.SCRIPT;
} else if (value.toLowerCase() === 'none') {
action = Actions.NONE;
} else {
action = Actions.BROWSER;
}
return { action, value };
}
function executeNodeScript(scriptPath, url) {
const extraArgs = process.argv.slice(2);
const child = spawn('node', [scriptPath, ...extraArgs, url], {
stdio: 'inherit',
});
child.on('close', code => {
if (code !== 0) {
console.log();
console.log(
chalk.red(
'The script specified as BROWSER environment variable failed.'
)
);
console.log(chalk.cyan(scriptPath) + ' exited with code ' + code + '.');
console.log();
return;
}
});
return true;
}
function startBrowserProcess(browser, url) {
// If we're on OS X, the user hasn't specifically
// requested a different browser, we can try opening
// Chrome with AppleScript. This lets us reuse an
// existing tab when possible instead of creating a new one.
const shouldTryOpenChromeWithAppleScript = process.platform === 'darwin' &&
(typeof browser !== 'string' || browser === OSX_CHROME);
if (shouldTryOpenChromeWithAppleScript) {
try {
// Try our best to reuse existing tab
// on OS X Google Chrome with AppleScript
execSync('ps cax | grep "Google Chrome"');
execSync('osascript openChrome.applescript ' + url, {
cwd: __dirname,
stdio: 'ignore',
});
return true;
} catch (err) {
// Ignore errors.
}
}
// Another special case: on OS X, check if BROWSER has been set to "open".
// In this case, instead of passing `open` to `opn` (which won't work),
// just ignore it (thus ensuring the intended behavior, i.e. opening the system browser):
// https://github.com/facebookincubator/create-react-app/pull/1690#issuecomment-283518768
if (process.platform === 'darwin' && browser === 'open') {
browser = undefined;
}
// Fallback to opn
// (It will always open new tab)
try {
var options = { app: browser };
opn(url, options).catch(() => {}); // Prevent `unhandledRejection` error.
return true;
} catch (err) {
return false;
}
}
/**
* Reads the BROWSER evironment variable and decides what to do with it. Returns
* true if it opened a browser or ran a node.js script, otherwise false.
*/
function openBrowser(url) {
const { action, value } = getBrowserEnv();
switch (action) {
case Actions.NONE:
// Special case: BROWSER="none" will prevent opening completely.
return false;
case Actions.SCRIPT:
return executeNodeScript(value, url);
case Actions.BROWSER:
return startBrowserProcess(value, url);
default:
throw new Error('Not implemented.');
}
}
module.exports = openBrowser;