diff --git a/packages/react-dev-utils/WatchChangedNodeModulesPlugin.js b/packages/react-dev-utils/WatchChangedNodeModulesPlugin.js new file mode 100644 index 00000000000..19475f5d182 --- /dev/null +++ b/packages/react-dev-utils/WatchChangedNodeModulesPlugin.js @@ -0,0 +1,33 @@ +/** + * 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. + */ + +// This Webpack plugin ensures that any change in node_modules package.json forces a project rebuild. + +'use strict'; + +var fs = require('fs'); + +var timeout; + +class WatchChangedNodeModulesPlugin { + constructor(nodeModulesPath) { + this.nodeModulesPath = nodeModulesPath; + } + + apply(compiler) { + fs.watch( + this.nodeModulesPath, + { persistent: false, recursive: true }, + () => { + clearTimeout(timeout); + timeout = setTimeout(() => compiler.run(() => {}), 1000); + } + ); + } +} + +module.exports = WatchChangedNodeModulesPlugin; diff --git a/packages/react-dev-utils/package.json b/packages/react-dev-utils/package.json index 05bddedae05..7f7e0c39cfc 100644 --- a/packages/react-dev-utils/package.json +++ b/packages/react-dev-utils/package.json @@ -33,6 +33,7 @@ "openChrome.applescript", "printHostingInstructions.js", "WatchMissingNodeModulesPlugin.js", + "WatchChangedNodeModulesPlugin.js", "WebpackDevServerUtils.js", "webpackHotDevClient.js" ], diff --git a/packages/react-scripts/config/webpack.config.dev.js b/packages/react-scripts/config/webpack.config.dev.js index c07819594b0..fd1572bedc5 100644 --- a/packages/react-scripts/config/webpack.config.dev.js +++ b/packages/react-scripts/config/webpack.config.dev.js @@ -15,6 +15,7 @@ const HtmlWebpackPlugin = require('html-webpack-plugin'); const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin'); const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin'); const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin'); +const WatchChangedNodeModulesPlugin = require('react-dev-utils/WatchChangedNodeModulesPlugin'); const eslintFormatter = require('react-dev-utils/eslintFormatter'); const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin'); const getClientEnvironment = require('./env'); @@ -333,11 +334,16 @@ module.exports = { // a plugin that prints an error when you attempt to do this. // See https://github.com/facebook/create-react-app/issues/240 new CaseSensitivePathsPlugin(), - // If you require a missing module and then `npm install` it, you still have + // If you require a missing module and then `yarn add` it, you still have // to restart the development server for Webpack to discover it. This plugin // makes the discovery automatic so you don't have to restart. // See https://github.com/facebook/create-react-app/issues/186 new WatchMissingNodeModulesPlugin(paths.appNodeModules), + // If you upgrade package version, you still have to restart the development + // server for Webpack to discover it. This plugin makes the discovery automatic + // so you don't have to restart. + // and https://github.com/facebook/create-react-app/issues/2956 + new WatchChangedNodeModulesPlugin(paths.appNodeModules), // Moment.js is an extremely popular library that bundles large locale files // by default due to how Webpack interprets its code. This is a practical // solution that requires the user to opt into importing specific locales.