123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- /**
- * Copyright (c) 2015-present, Facebook, Inc.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file at
- * https://github.com/facebook/create-react-app/blob/master/LICENSE
- */
- const open = require('open')
- const execa = require('execa')
- const chalk = require('chalk')
- const execSync = require('child_process').execSync
- // https://github.com/sindresorhus/open#app
- const 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/open#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 = execa('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 "' + encodeURI(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 the string `open` to `open` function (which won't work),
- // just ignore it (thus ensuring the intended behavior, i.e. opening the system browser):
- // https://github.com/facebook/create-react-app/pull/1690#issuecomment-283518768
- if (process.platform === 'darwin' && browser === 'open') {
- browser = undefined
- }
- // Fallback to open
- // (It will always open new tab)
- try {
- var options = { app: browser, url: true }
- open(url, options).catch(() => {}) // Prevent `unhandledRejection` error.
- return true
- } catch (err) {
- return false
- }
- }
- /**
- * Reads the BROWSER environment variable and decides what to do with it. Returns
- * true if it opened a browser or ran a node.js script, otherwise false.
- */
- exports.openBrowser = function (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.')
- }
- }
|