From b7e99866f734547818aabde017bbb98d4232c79a Mon Sep 17 00:00:00 2001 From: Ian Sutherland Date: Wed, 22 Jul 2020 11:50:51 -0600 Subject: [PATCH 1/2] Add Fast Refresh warning when using React < 16.10 --- docusaurus/docs/advanced-configuration.md | 2 +- packages/react-dev-utils/webpackHotDevClient.js | 2 +- packages/react-scripts/config/env.js | 2 +- packages/react-scripts/config/webpack.config.js | 2 +- packages/react-scripts/scripts/start.js | 16 ++++++++++++++++ 5 files changed, 20 insertions(+), 4 deletions(-) diff --git a/docusaurus/docs/advanced-configuration.md b/docusaurus/docs/advanced-configuration.md index 958f9ac3168..a4073a24b31 100644 --- a/docusaurus/docs/advanced-configuration.md +++ b/docusaurus/docs/advanced-configuration.md @@ -25,5 +25,5 @@ You can adjust various development and production settings by setting environmen | INLINE_RUNTIME_CHUNK | 🚫 Ignored | ✅ Used | By default, Create React App will embed the runtime script into `index.html` during the production build. When set to `false`, the script will not be embedded and will be imported as usual. This is normally required when dealing with CSP. | | IMAGE_INLINE_SIZE_LIMIT | 🚫 Ignored | ✅ Used | By default, images smaller than 10,000 bytes are encoded as a data URI in base64 and inlined in the CSS or JS build artifact. Set this to control the size limit in bytes. Setting it to 0 will disable the inlining of images. | | EXTEND_ESLINT | ✅ Used | ✅ Used | When set to `true`, user provided ESLint configs will be used by `eslint-loader`. Note that any rules set to `"error"` will stop the application from building. | -| FAST_REFRESH | ✅ Used | 🚫 Ignored | When set to `true`, enables experimental support for fast refresh to allow you to tweak your components in real time without reloading the page. | +| FAST_REFRESH | ✅ Used | 🚫 Ignored | When set to `false`, disables experimental support for Fast Refresh to allow you to tweak your components in real time without reloading the page. | | TSC_COMPILE_ON_ERROR | ✅ Used | ✅ Used | When set to `true`, you can run and properly build TypeScript projects even if there are TypeScript type check errors. These errors are printed as warnings in the terminal and/or browser console. | diff --git a/packages/react-dev-utils/webpackHotDevClient.js b/packages/react-dev-utils/webpackHotDevClient.js index f9d814fdd11..16198d3374a 100644 --- a/packages/react-dev-utils/webpackHotDevClient.js +++ b/packages/react-dev-utils/webpackHotDevClient.js @@ -243,7 +243,7 @@ function tryApplyUpdates(onHotUpdateSuccess) { } function handleApplyUpdates(err, updatedModules) { - const hasReactRefresh = process.env.FAST_REFRESH; + const hasReactRefresh = process.env.FAST_REFRESH !== 'false'; const wantsForcedReload = err || !updatedModules || hadRuntimeError; // React refresh can handle hot-reloading over errors. if (!hasReactRefresh && wantsForcedReload) { diff --git a/packages/react-scripts/config/env.js b/packages/react-scripts/config/env.js index 850b0cfa480..0ad47cb9779 100644 --- a/packages/react-scripts/config/env.js +++ b/packages/react-scripts/config/env.js @@ -97,7 +97,7 @@ function getClientEnvironment(publicUrl) { // react-refresh is not 100% stable at this time, // which is why it's disabled by default. // It is defined here so it is available in the webpackHotDevClient. - FAST_REFRESH: process.env.FAST_REFRESH || false, + FAST_REFRESH: process.env.FAST_REFRESH !== 'false', } ); // Stringify all values so we can feed into webpack DefinePlugin diff --git a/packages/react-scripts/config/webpack.config.js b/packages/react-scripts/config/webpack.config.js index 1dba35cf903..0fdf3f6d332 100644 --- a/packages/react-scripts/config/webpack.config.js +++ b/packages/react-scripts/config/webpack.config.js @@ -86,7 +86,7 @@ module.exports = function (webpackEnv) { // Get environment variables to inject into our app. const env = getClientEnvironment(paths.publicUrlOrPath.slice(0, -1)); - const shouldUseReactRefresh = env.raw.FAST_REFRESH; + const shouldUseReactRefresh = env.raw.FAST_REFRESH !== 'false'; // common function to get style loaders const getStyleLoaders = (cssOptions, preProcessor) => { diff --git a/packages/react-scripts/scripts/start.js b/packages/react-scripts/scripts/start.js index daa98423f1a..441005b462f 100644 --- a/packages/react-scripts/scripts/start.js +++ b/packages/react-scripts/scripts/start.js @@ -47,7 +47,11 @@ const openBrowser = require('react-dev-utils/openBrowser'); const paths = require('../config/paths'); const configFactory = require('../config/webpack.config'); const createDevServerConfig = require('../config/webpackDevServer.config'); +const getClientEnvironment = require('../config/env'); +const react = require('react'); +const semver = require('semver'); +const env = getClientEnvironment(paths.publicUrlOrPath.slice(0, -1)); const useYarn = fs.existsSync(paths.yarnLockFile); const isInteractive = process.stdout.isTTY; @@ -95,6 +99,7 @@ checkBrowsers(paths.appPath, isInteractive) const config = configFactory('development'); const protocol = process.env.HTTPS === 'true' ? 'https' : 'http'; const appName = require(paths.appPackageJson).name; + const useTypeScript = fs.existsSync(paths.appTsConfig); const tscCompileOnError = process.env.TSC_COMPILE_ON_ERROR === 'true'; const urls = prepareUrls( @@ -142,6 +147,17 @@ checkBrowsers(paths.appPath, isInteractive) clearConsole(); } + if ( + env.raw.FAST_REFRES !== 'false' && + semver.lt(react.version, '16.10.0') + ) { + console.log( + chalk.yellow( + `Fast Refresh requires React 16.10 or higher. You are using React ${react.version}.` + ) + ); + } + console.log(chalk.cyan('Starting the development server...\n')); openBrowser(urls.localUrlForBrowser); }); From 743bf29d43af148886c8031eca274ca85e7df528 Mon Sep 17 00:00:00 2001 From: Ian Sutherland Date: Fri, 24 Jul 2020 10:27:00 -0600 Subject: [PATCH 2/2] Update React import --- packages/react-scripts/config/webpack.config.js | 2 +- packages/react-scripts/scripts/start.js | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/packages/react-scripts/config/webpack.config.js b/packages/react-scripts/config/webpack.config.js index 0fdf3f6d332..1dba35cf903 100644 --- a/packages/react-scripts/config/webpack.config.js +++ b/packages/react-scripts/config/webpack.config.js @@ -86,7 +86,7 @@ module.exports = function (webpackEnv) { // Get environment variables to inject into our app. const env = getClientEnvironment(paths.publicUrlOrPath.slice(0, -1)); - const shouldUseReactRefresh = env.raw.FAST_REFRESH !== 'false'; + const shouldUseReactRefresh = env.raw.FAST_REFRESH; // common function to get style loaders const getStyleLoaders = (cssOptions, preProcessor) => { diff --git a/packages/react-scripts/scripts/start.js b/packages/react-scripts/scripts/start.js index 441005b462f..ffbb15d1204 100644 --- a/packages/react-scripts/scripts/start.js +++ b/packages/react-scripts/scripts/start.js @@ -44,12 +44,12 @@ const { prepareUrls, } = require('react-dev-utils/WebpackDevServerUtils'); const openBrowser = require('react-dev-utils/openBrowser'); +const semver = require('semver'); const paths = require('../config/paths'); const configFactory = require('../config/webpack.config'); const createDevServerConfig = require('../config/webpackDevServer.config'); const getClientEnvironment = require('../config/env'); -const react = require('react'); -const semver = require('semver'); +const react = require(require.resolve('react', { paths: [paths.appPath] })); const env = getClientEnvironment(paths.publicUrlOrPath.slice(0, -1)); const useYarn = fs.existsSync(paths.yarnLockFile); @@ -147,10 +147,7 @@ checkBrowsers(paths.appPath, isInteractive) clearConsole(); } - if ( - env.raw.FAST_REFRES !== 'false' && - semver.lt(react.version, '16.10.0') - ) { + if (env.raw.FAST_REFRESH && semver.lt(react.version, '16.10.0')) { console.log( chalk.yellow( `Fast Refresh requires React 16.10 or higher. You are using React ${react.version}.`