diff --git a/packages/react-dev-utils/README.md b/packages/react-dev-utils/README.md index 034790c2288..1010f1ac470 100644 --- a/packages/react-dev-utils/README.md +++ b/packages/react-dev-utils/README.md @@ -105,6 +105,19 @@ module.exports = { } ``` +#### `addProcessExitHandlers(): void` + +Exits the process when stdin is closed by an external program.
+This is useful when the dev server is started by some other tool (i.e.: Phoenix) +which then uses the standard Unix convention of closing the standard input to +signal the end of the program. + +```js +var addProcessExitHandlers = require('react-dev-utils/addProcessExitHandlers'); + +addProcessExitHandlers(); +``` + #### `checkRequiredFiles(files: Array): boolean` Makes sure that all passed files exist.
diff --git a/packages/react-dev-utils/addProcessExitHandlers.js b/packages/react-dev-utils/addProcessExitHandlers.js new file mode 100644 index 00000000000..fac1f3bb40f --- /dev/null +++ b/packages/react-dev-utils/addProcessExitHandlers.js @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +'use strict'; + +function addProcessExitHandlers(argv) { + // Issue: https://github.com/facebookincubator/create-react-app/issues/1753 + // The below lines are added to make sure that this process is + // exited when stdin is ended. The consequence of not doing this means + // that all watch processes will stay running despite the process that spawned + // them being closed. + argv = argv || process.argv; + const watchStdinIndex = argv.indexOf('--watch-stdin'); + const shouldWatchStdin = watchStdinIndex > -1; + if (shouldWatchStdin) { + argv.splice(watchStdinIndex, 1); + process.stdin.on('end', function() { + process.exit(0); + }); + process.stdin.resume(); + } +} + +module.exports = addProcessExitHandlers; diff --git a/packages/react-dev-utils/package.json b/packages/react-dev-utils/package.json index db7114a261a..6e5614dbcb0 100644 --- a/packages/react-dev-utils/package.json +++ b/packages/react-dev-utils/package.json @@ -11,6 +11,7 @@ "node": ">=6" }, "files": [ + "addProcessExitHandlers.js", "checkRequiredFiles.js", "clearConsole.js", "crashOverlay.js", diff --git a/packages/react-scripts/config/webpack.config.prod.js b/packages/react-scripts/config/webpack.config.prod.js index c32eb0f08a7..457a9672892 100644 --- a/packages/react-scripts/config/webpack.config.prod.js +++ b/packages/react-scripts/config/webpack.config.prod.js @@ -301,7 +301,7 @@ module.exports = { }, mangle: { safari10: true, - }, + }, output: { comments: false, // Turned on because emoji and regex is not minified properly using default diff --git a/packages/react-scripts/scripts/start.js b/packages/react-scripts/scripts/start.js index 8df052d3bbb..e552ba94fc0 100644 --- a/packages/react-scripts/scripts/start.js +++ b/packages/react-scripts/scripts/start.js @@ -38,6 +38,7 @@ const openBrowser = require('react-dev-utils/openBrowser'); const paths = require('../config/paths'); const config = require('../config/webpack.config.dev'); const createDevServerConfig = require('../config/webpackDevServer.config'); +const addProcessExitHandlers = require('react-dev-utils/addProcessExitHandlers'); const useYarn = fs.existsSync(paths.yarnLockFile); const isInteractive = process.stdout.isTTY; @@ -47,6 +48,8 @@ if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) { process.exit(1); } +addProcessExitHandlers(); + // Tools like Cloud9 rely on this. const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000; const HOST = process.env.HOST || '0.0.0.0'; diff --git a/packages/react-scripts/scripts/test.js b/packages/react-scripts/scripts/test.js index b30113fe662..f0b38f5f641 100644 --- a/packages/react-scripts/scripts/test.js +++ b/packages/react-scripts/scripts/test.js @@ -23,12 +23,16 @@ process.on('unhandledRejection', err => { // Ensure environment variables are read. require('../config/env'); +const addProcessExitHandlers = require('react-dev-utils/addProcessExitHandlers'); const jest = require('jest'); const argv = process.argv.slice(2); // Watch unless on CI or in coverage mode +// Exit process when stdin ends only when watch mode enabled if (!process.env.CI && argv.indexOf('--coverage') < 0) { argv.push('--watch'); + + addProcessExitHandlers(argv); } // @remove-on-eject-begin diff --git a/packages/react-scripts/template/README.md b/packages/react-scripts/template/README.md index b8c0b74df39..027d6078c56 100644 --- a/packages/react-scripts/template/README.md +++ b/packages/react-scripts/template/README.md @@ -2218,12 +2218,22 @@ To resolve this: 1. Open an issue on the dependency's issue tracker and ask that the package be published pre-compiled. * Note: Create React App can consume both CommonJS and ES modules. For Node.js compatibility, it is recommended that the main entry point is CommonJS. However, they can optionally provide an ES module entry point with the `module` field in `package.json`. Note that **even if a library provides an ES Modules version, it should still precompile other ES6 features to ES5 if it intends to support older browsers**. -2. Fork the package and publish a corrected version yourself. +2. Fork the package and publish a corrected version yourself. 3. If the dependency is small enough, copy it to your `src/` folder and treat it as application code. In the future, we might start automatically compiling incompatible third-party modules, but it is not currently supported. This approach would also slow down the production builds. +### Phoenix doesn't kill the webpack-dev-server + +When using create-react-app in a Phoenix application, the webpack-dev-server is not closed automatically if it's configured as a watcher. This is because Phoenix expects the watchers to close when the standart input is closed. + +To watch for standart input you can pass the `--watch-stdin` option: + +``` +npm start -- --watch-stdin +``` + ## Something Missing? If you have ideas for more “How To” recipes that should be on this page, [let us know](https://github.com/facebookincubator/create-react-app/issues) or [contribute some!](https://github.com/facebookincubator/create-react-app/edit/master/packages/react-scripts/template/README.md)