From cdb7ec0606a880687dc4db20a9e8982f4b9a1fe7 Mon Sep 17 00:00:00 2001 From: "Morten N.O. Henriksen" Date: Wed, 27 Jan 2021 19:36:02 +0100 Subject: [PATCH 01/59] Revert "Revert "Update postcss packages" (#10216)" This reverts commit 39689239c18a1d77fb303e285b26beb1a4b650c0. --- .../react-scripts/config/webpack.config.js | 36 ++++++++++--------- packages/react-scripts/package.json | 7 ++-- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/packages/react-scripts/config/webpack.config.js b/packages/react-scripts/config/webpack.config.js index 502736ead11..bc95e661c4a 100644 --- a/packages/react-scripts/config/webpack.config.js +++ b/packages/react-scripts/config/webpack.config.js @@ -125,23 +125,25 @@ module.exports = function (webpackEnv) { // package.json loader: require.resolve('postcss-loader'), options: { - // Necessary for external CSS imports to work - // https://github.com/facebook/create-react-app/issues/2677 - ident: 'postcss', - plugins: () => [ - require('postcss-flexbugs-fixes'), - require('postcss-preset-env')({ - autoprefixer: { - flexbox: 'no-2009', - }, - stage: 3, - }), - // Adds PostCSS Normalize as the reset css with default options, - // so that it honors browserslist config in package.json - // which in turn let's users customize the target behavior as per their needs. - postcssNormalize(), - ], - sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment, + postcssOptions: { + plugins: [ + require('postcss-flexbugs-fixes'), + [ + require('postcss-preset-env'), + { + autoprefixer: { + flexbox: 'no-2009', + }, + stage: 3, + }, + ], + // Adds PostCSS Normalize as the reset css with default options, + // so that it honors browserslist config in package.json + // which in turn let's users customize the target behavior as per their needs. + postcssNormalize(), + ], + }, + sourceMap: isEnvProduction && shouldUseSourceMap, }, }, ].filter(Boolean); diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json index c7fe2920ed9..abed557c4e6 100644 --- a/packages/react-scripts/package.json +++ b/packages/react-scripts/package.json @@ -65,9 +65,10 @@ "mini-css-extract-plugin": "0.11.3", "optimize-css-assets-webpack-plugin": "5.0.4", "pnp-webpack-plugin": "1.6.4", - "postcss-flexbugs-fixes": "4.2.1", - "postcss-loader": "3.0.0", - "postcss-normalize": "8.0.1", + "postcss": "8.1.14", + "postcss-flexbugs-fixes": "5.0.2", + "postcss-loader": "4.1.0", + "postcss-normalize": "9.0.0", "postcss-preset-env": "6.7.0", "postcss-safe-parser": "5.0.2", "prompts": "2.4.0", From 79b16d4d3b184077d8d4e383a5d92831d3f4be60 Mon Sep 17 00:00:00 2001 From: Ian Schmitz Date: Mon, 7 Dec 2020 21:47:04 -0800 Subject: [PATCH 02/59] Revert "Update postcss packages" (#10216) This reverts commit 580ed5d9b00f452b1743c88cb950cbd341e891e1. --- .../react-scripts/config/webpack.config.js | 36 +++++++++---------- packages/react-scripts/package.json | 7 ++-- 2 files changed, 20 insertions(+), 23 deletions(-) diff --git a/packages/react-scripts/config/webpack.config.js b/packages/react-scripts/config/webpack.config.js index 51c0234698c..26c2a65aad0 100644 --- a/packages/react-scripts/config/webpack.config.js +++ b/packages/react-scripts/config/webpack.config.js @@ -128,25 +128,23 @@ module.exports = function (webpackEnv) { // package.json loader: require.resolve('postcss-loader'), options: { - postcssOptions: { - plugins: [ - require('postcss-flexbugs-fixes'), - [ - require('postcss-preset-env'), - { - autoprefixer: { - flexbox: 'no-2009', - }, - stage: 3, - }, - ], - // Adds PostCSS Normalize as the reset css with default options, - // so that it honors browserslist config in package.json - // which in turn let's users customize the target behavior as per their needs. - postcssNormalize(), - ], - }, - sourceMap: isEnvProduction && shouldUseSourceMap, + // Necessary for external CSS imports to work + // https://github.com/facebook/create-react-app/issues/2677 + ident: 'postcss', + plugins: () => [ + require('postcss-flexbugs-fixes'), + require('postcss-preset-env')({ + autoprefixer: { + flexbox: 'no-2009', + }, + stage: 3, + }), + // Adds PostCSS Normalize as the reset css with default options, + // so that it honors browserslist config in package.json + // which in turn let's users customize the target behavior as per their needs. + postcssNormalize(), + ], + sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment, }, }, ].filter(Boolean); diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json index b47a46c4cae..ffae0fa304b 100644 --- a/packages/react-scripts/package.json +++ b/packages/react-scripts/package.json @@ -65,10 +65,9 @@ "mini-css-extract-plugin": "0.11.3", "optimize-css-assets-webpack-plugin": "5.0.4", "pnp-webpack-plugin": "1.6.4", - "postcss": "8.1.14", - "postcss-flexbugs-fixes": "5.0.2", - "postcss-loader": "4.1.0", - "postcss-normalize": "9.0.0", + "postcss-flexbugs-fixes": "4.2.1", + "postcss-loader": "3.0.0", + "postcss-normalize": "8.0.1", "postcss-preset-env": "6.7.0", "postcss-safe-parser": "5.0.2", "prompts": "2.4.0", From 8d5d16f29204c295dabb2b65c8f55fe5b121ec84 Mon Sep 17 00:00:00 2001 From: "Morten N.O. Henriksen" Date: Wed, 27 Jan 2021 20:03:04 +0100 Subject: [PATCH 03/59] Update postcss and loader --- packages/react-scripts/package.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json index ffae0fa304b..6fddb9d8e40 100644 --- a/packages/react-scripts/package.json +++ b/packages/react-scripts/package.json @@ -65,9 +65,10 @@ "mini-css-extract-plugin": "0.11.3", "optimize-css-assets-webpack-plugin": "5.0.4", "pnp-webpack-plugin": "1.6.4", - "postcss-flexbugs-fixes": "4.2.1", - "postcss-loader": "3.0.0", - "postcss-normalize": "8.0.1", + "postcss": "8.2.4", + "postcss-flexbugs-fixes": "5.0.2", + "postcss-loader": "4.2.0", + "postcss-normalize": "9.0.0", "postcss-preset-env": "6.7.0", "postcss-safe-parser": "5.0.2", "prompts": "2.4.0", From 0254dc9d4e90af4f420e7cfc83a3c8b81e111fa3 Mon Sep 17 00:00:00 2001 From: "Morten N.O. Henriksen" Date: Wed, 4 Nov 2020 00:49:02 +0100 Subject: [PATCH 04/59] Update fork-ts-checker-webpack-plugin@5.2.1 References: * [hook rename](https://github.com/TypeStrong/fork-ts-checker-webpack-plugin/issues/490) * [include/exclude](https://github.com/TypeStrong/fork-ts-checker-webpack-plugin/issues/450) and [issue options](https://github.com/TypeStrong/fork-ts-checker-webpack-plugin#issues-options) * [release notes 5.0.0](https://github.com/TypeStrong/fork-ts-checker-webpack-plugin/releases/tag/v5.0.0) --- .../react-dev-utils/WebpackDevServerUtils.js | 2 +- packages/react-dev-utils/package.json | 2 +- .../react-scripts/config/webpack.config.js | 55 ++++++++++++------- 3 files changed, 37 insertions(+), 22 deletions(-) diff --git a/packages/react-dev-utils/WebpackDevServerUtils.js b/packages/react-dev-utils/WebpackDevServerUtils.js index 6a56f666aa1..8d4637853b8 100644 --- a/packages/react-dev-utils/WebpackDevServerUtils.js +++ b/packages/react-dev-utils/WebpackDevServerUtils.js @@ -148,7 +148,7 @@ function createCompiler({ forkTsCheckerWebpackPlugin .getCompilerHooks(compiler) - .receive.tap('afterTypeScriptCheck', (diagnostics, lints) => { + .issues.tap('afterTypeScriptCheck', (diagnostics, lints) => { const allMsgs = [...diagnostics, ...lints]; const format = message => `${message.file}\n${typescriptFormatter(message, true)}`; diff --git a/packages/react-dev-utils/package.json b/packages/react-dev-utils/package.json index 77a41ebe588..69309216c82 100644 --- a/packages/react-dev-utils/package.json +++ b/packages/react-dev-utils/package.json @@ -61,7 +61,7 @@ "escape-string-regexp": "2.0.0", "filesize": "6.1.0", "find-up": "4.1.0", - "fork-ts-checker-webpack-plugin": "4.1.6", + "fork-ts-checker-webpack-plugin": "5.2.1", "global-modules": "2.0.0", "globby": "11.0.1", "gzip-size": "5.1.1", diff --git a/packages/react-scripts/config/webpack.config.js b/packages/react-scripts/config/webpack.config.js index 26c2a65aad0..9b1ba814518 100644 --- a/packages/react-scripts/config/webpack.config.js +++ b/packages/react-scripts/config/webpack.config.js @@ -725,31 +725,46 @@ module.exports = function (webpackEnv) { // TypeScript type checking useTypeScript && new ForkTsCheckerWebpackPlugin({ - typescript: resolve.sync('typescript', { - basedir: paths.appNodeModules, - }), async: isEnvDevelopment, - checkSyntacticErrors: true, - resolveModuleNameModule: process.versions.pnp - ? `${__dirname}/pnpTs.js` - : undefined, - resolveTypeReferenceDirectiveModule: process.versions.pnp - ? `${__dirname}/pnpTs.js` - : undefined, - tsconfig: paths.appTsConfig, - reportFiles: [ + typescript: { + typescriptPath: resolve.sync('typescript', { + basedir: paths.appNodeModules, + }), + configOverwrite: { + compilerOptions: { + sourceMap: isEnvProduction + ? shouldUseSourceMap + : isEnvDevelopment, + skipLibCheck: true, + inlineSourceMap: false, + declarationMap: false, + noEmit: true, + incremental: true, + }, + }, + context: paths.appPath, + diagnosticOptions: { + syntactic: true, + }, + mode: 'write-references', + // profile: true, + }, + issue: { // This one is specifically to match during CI tests, // as micromatch doesn't match // '../cra-template-typescript/template/src/App.tsx' // otherwise. - '../**/src/**/*.{ts,tsx}', - '**/src/**/*.{ts,tsx}', - '!**/src/**/__tests__/**', - '!**/src/**/?(*.)(spec|test).*', - '!**/src/setupProxy.*', - '!**/src/setupTests.*', - ], - silent: true, + include: ['../**/src/**/*.{ts,tsx}', '**/src/**/*.{ts,tsx}'], + exclude: [ + '**/src/**/__tests__/**', + '**/src/**/?(*.)(spec|test).*', + '**/src/setupProxy.*', + '**/src/setupTests.*', + ], + }, + logger: { + infrastructure: 'silent', + }, // The formatter is invoked directly in WebpackDevServerUtils during development formatter: isEnvProduction ? typescriptFormatter : undefined, }), From 6777da0eb7f763795550024968923da259d1af56 Mon Sep 17 00:00:00 2001 From: "Morten N.O. Henriksen" Date: Sat, 5 Dec 2020 10:26:45 +0100 Subject: [PATCH 05/59] Update fork-ts-checker-webpack-plugin 6.0.5 --- packages/react-dev-utils/README.md | 6 +- .../react-dev-utils/WebpackDevServerUtils.js | 69 ++----------------- packages/react-dev-utils/package.json | 2 +- .../react-dev-utils/typescriptFormatter.js | 45 ------------ .../react-scripts/config/webpack.config.js | 10 +-- packages/react-scripts/scripts/start.js | 2 - 6 files changed, 14 insertions(+), 120 deletions(-) delete mode 100644 packages/react-dev-utils/typescriptFormatter.js diff --git a/packages/react-dev-utils/README.md b/packages/react-dev-utils/README.md index 6a6ab28b32f..262b9a51685 100644 --- a/packages/react-dev-utils/README.md +++ b/packages/react-dev-utils/README.md @@ -231,11 +231,11 @@ var formatWebpackMessages = require('react-dev-utils/formatWebpackMessages'); var compiler = webpack(config); -compiler.hooks.invalid.tap('invalid', function() { +compiler.hooks.invalid.tap('invalid', function () { console.log('Compiling...'); }); -compiler.hooks.done.tap('done', function(stats) { +compiler.hooks.done.tap('done', function (stats) { var rawMessages = stats.toJson({}, true); var messages = formatWebpackMessages(rawMessages); if (!messages.errors.length && !messages.warnings.length) { @@ -338,11 +338,9 @@ The `args` object accepts a number of properties: - **appName** `string`: The name that will be printed to the terminal. - **config** `Object`: The webpack configuration options to be provided to the webpack constructor. -- **devSocket** `Object`: Required if `useTypeScript` is `true`. This object should include `errors` and `warnings` which are functions accepting an array of errors or warnings emitted by the type checking. This is useful when running `fork-ts-checker-webpack-plugin` with `async: true` to report errors that are emitted after the webpack build is complete. - **urls** `Object`: To provide the `urls` argument, use `prepareUrls()` described below. - **useYarn** `boolean`: If `true`, yarn instructions will be emitted in the terminal instead of npm. - **useTypeScript** `boolean`: If `true`, TypeScript type checking will be enabled. Be sure to provide the `devSocket` argument above if this is set to `true`. -- **tscCompileOnError** `boolean`: If `true`, errors in TypeScript type checking will not prevent start script from running app, and will not cause build script to exit unsuccessfully. Also downgrades all TypeScript type checking error messages to warning messages. - **webpack** `function`: A reference to the webpack constructor. ##### `prepareProxy(proxySetting: string, appPublicFolder: string, servedPathname: string): Object` diff --git a/packages/react-dev-utils/WebpackDevServerUtils.js b/packages/react-dev-utils/WebpackDevServerUtils.js index 8d4637853b8..0193b070cbd 100644 --- a/packages/react-dev-utils/WebpackDevServerUtils.js +++ b/packages/react-dev-utils/WebpackDevServerUtils.js @@ -17,7 +17,6 @@ const prompts = require('prompts'); const clearConsole = require('./clearConsole'); const formatWebpackMessages = require('./formatWebpackMessages'); const getProcessForPort = require('./getProcessForPort'); -const typescriptFormatter = require('./typescriptFormatter'); const forkTsCheckerWebpackPlugin = require('./ForkTsCheckerWebpackPlugin'); const isInteractive = process.stdout.isTTY; @@ -104,11 +103,9 @@ function printInstructions(appName, urls, useYarn) { function createCompiler({ appName, config, - devSocket, urls, useYarn, useTypeScript, - tscCompileOnError, webpack, }) { // "Compiler" is a low-level interface to webpack. @@ -137,28 +134,16 @@ function createCompiler({ let isFirstCompile = true; let tsMessagesPromise; - let tsMessagesResolver; if (useTypeScript) { - compiler.hooks.beforeCompile.tap('beforeCompile', () => { - tsMessagesPromise = new Promise(resolve => { - tsMessagesResolver = msgs => resolve(msgs); - }); - }); - forkTsCheckerWebpackPlugin .getCompilerHooks(compiler) - .issues.tap('afterTypeScriptCheck', (diagnostics, lints) => { - const allMsgs = [...diagnostics, ...lints]; - const format = message => - `${message.file}\n${typescriptFormatter(message, true)}`; - - tsMessagesResolver({ - errors: allMsgs.filter(msg => msg.severity === 'error').map(format), - warnings: allMsgs - .filter(msg => msg.severity === 'warning') - .map(format), - }); + .waiting.tap('awaitingTypeScriptCheck', () => { + console.log( + chalk.yellow( + 'Files successfully emitted, waiting for typecheck results...' + ) + ); }); } @@ -180,48 +165,6 @@ function createCompiler({ errors: true, }); - if (useTypeScript && statsData.errors.length === 0) { - const delayedMsg = setTimeout(() => { - console.log( - chalk.yellow( - 'Files successfully emitted, waiting for typecheck results...' - ) - ); - }, 100); - - const messages = await tsMessagesPromise; - clearTimeout(delayedMsg); - if (tscCompileOnError) { - statsData.warnings.push(...messages.errors); - } else { - statsData.errors.push(...messages.errors); - } - statsData.warnings.push(...messages.warnings); - - // Push errors and warnings into compilation result - // to show them after page refresh triggered by user. - if (tscCompileOnError) { - stats.compilation.warnings.push(...messages.errors); - } else { - stats.compilation.errors.push(...messages.errors); - } - stats.compilation.warnings.push(...messages.warnings); - - if (messages.errors.length > 0) { - if (tscCompileOnError) { - devSocket.warnings(messages.errors); - } else { - devSocket.errors(messages.errors); - } - } else if (messages.warnings.length > 0) { - devSocket.warnings(messages.warnings); - } - - if (isInteractive) { - clearConsole(); - } - } - const messages = formatWebpackMessages(statsData); const isSuccessful = !messages.errors.length && !messages.warnings.length; if (isSuccessful) { diff --git a/packages/react-dev-utils/package.json b/packages/react-dev-utils/package.json index 69309216c82..da1c24c85cb 100644 --- a/packages/react-dev-utils/package.json +++ b/packages/react-dev-utils/package.json @@ -61,7 +61,7 @@ "escape-string-regexp": "2.0.0", "filesize": "6.1.0", "find-up": "4.1.0", - "fork-ts-checker-webpack-plugin": "5.2.1", + "fork-ts-checker-webpack-plugin": "6.0.5", "global-modules": "2.0.0", "globby": "11.0.1", "gzip-size": "5.1.1", diff --git a/packages/react-dev-utils/typescriptFormatter.js b/packages/react-dev-utils/typescriptFormatter.js deleted file mode 100644 index 1fb1276c6bd..00000000000 --- a/packages/react-dev-utils/typescriptFormatter.js +++ /dev/null @@ -1,45 +0,0 @@ -/** - * 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'; - -const os = require('os'); -const codeFrame = require('@babel/code-frame').codeFrameColumns; -const chalk = require('chalk'); -const fs = require('fs'); - -const issueOrigins = { - typescript: 'TypeScript', - internal: 'fork-ts-checker-webpack-plugin', -}; - -function formatter(issue) { - const { origin, severity, file, line, message, code, character } = issue; - - const colors = new chalk.constructor(); - const messageColor = severity === 'warning' ? colors.yellow : colors.red; - const fileAndNumberColor = colors.bold.cyan; - - const source = file && fs.existsSync(file) && fs.readFileSync(file, 'utf-8'); - const frame = source - ? codeFrame(source, { start: { line: line, column: character } }) - .split('\n') - .map(str => ' ' + str) - .join(os.EOL) - : ''; - - return [ - messageColor.bold(`${issueOrigins[origin]} ${severity.toLowerCase()} in `) + - fileAndNumberColor(`${file}(${line},${character})`) + - messageColor(':'), - message + ' ' + messageColor.underline(`TS${code}`), - '', - frame, - ].join(os.EOL); -} - -module.exports = formatter; diff --git a/packages/react-scripts/config/webpack.config.js b/packages/react-scripts/config/webpack.config.js index 9b1ba814518..d2dc9a5e4af 100644 --- a/packages/react-scripts/config/webpack.config.js +++ b/packages/react-scripts/config/webpack.config.js @@ -32,7 +32,6 @@ const modules = require('./modules'); const getClientEnvironment = require('./env'); const ModuleNotFoundPlugin = require('react-dev-utils/ModuleNotFoundPlugin'); const ForkTsCheckerWebpackPlugin = require('react-dev-utils/ForkTsCheckerWebpackPlugin'); -const typescriptFormatter = require('react-dev-utils/typescriptFormatter'); const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin'); // @remove-on-eject-begin const getCacheIdentifier = require('react-dev-utils/getCacheIdentifier'); @@ -754,19 +753,20 @@ module.exports = function (webpackEnv) { // as micromatch doesn't match // '../cra-template-typescript/template/src/App.tsx' // otherwise. - include: ['../**/src/**/*.{ts,tsx}', '**/src/**/*.{ts,tsx}'], + include: [ + '../**/src/**/*.{ts,tsx}', + '**/src/**/*.{ts,tsx}', + ].map(file => ({ file })), exclude: [ '**/src/**/__tests__/**', '**/src/**/?(*.)(spec|test).*', '**/src/setupProxy.*', '**/src/setupTests.*', - ], + ].map(file => ({ file })), }, logger: { infrastructure: 'silent', }, - // The formatter is invoked directly in WebpackDevServerUtils during development - formatter: isEnvProduction ? typescriptFormatter : undefined, }), !disableESLintPlugin && new ESLintPlugin({ diff --git a/packages/react-scripts/scripts/start.js b/packages/react-scripts/scripts/start.js index ffbb15d1204..4eb6ffdcf4e 100644 --- a/packages/react-scripts/scripts/start.js +++ b/packages/react-scripts/scripts/start.js @@ -118,11 +118,9 @@ checkBrowsers(paths.appPath, isInteractive) const compiler = createCompiler({ appName, config, - devSocket, urls, useYarn, useTypeScript, - tscCompileOnError, webpack, }); // Load proxy config From f959414c762777a58bbf8a7ea947a8e107a76085 Mon Sep 17 00:00:00 2001 From: "Morten N.O. Henriksen" Date: Wed, 4 Nov 2020 01:35:02 +0100 Subject: [PATCH 06/59] Add css-minimizer-webpack-plugin@1.1.5 remove Add css-minimizer-webpack-plugin@1.1.5 Remove optimize-css-assets-webpack-plugin and postcss-safe-parser References: * https://webpack.js.org/plugins/css-minimizer-webpack-plugin/ --- .../react-scripts/config/webpack.config.js | 30 ++++++++----------- packages/react-scripts/package.json | 3 +- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/packages/react-scripts/config/webpack.config.js b/packages/react-scripts/config/webpack.config.js index d2dc9a5e4af..b7fd81e5906 100644 --- a/packages/react-scripts/config/webpack.config.js +++ b/packages/react-scripts/config/webpack.config.js @@ -18,8 +18,7 @@ const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin'); const InlineChunkHtmlPlugin = require('react-dev-utils/InlineChunkHtmlPlugin'); const TerserPlugin = require('terser-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); -const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin'); -const safePostCssParser = require('postcss-safe-parser'); +const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); const ManifestPlugin = require('webpack-manifest-plugin'); const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin'); const WorkboxWebpackPlugin = require('workbox-webpack-plugin'); @@ -283,21 +282,18 @@ module.exports = function (webpackEnv) { sourceMap: shouldUseSourceMap, }), // This is only used in production mode - new OptimizeCSSAssetsPlugin({ - cssProcessorOptions: { - parser: safePostCssParser, - map: shouldUseSourceMap - ? { - // `inline: false` forces the sourcemap to be output into a - // separate file - inline: false, - // `annotation: true` appends the sourceMappingURL to the end of - // the css file, helping the browser find the sourcemap - annotation: true, - } - : false, - }, - cssProcessorPluginOptions: { + new CssMinimizerPlugin({ + sourceMap: shouldUseSourceMap + ? { + // `inline: false` forces the sourcemap to be output into a + // separate file + inline: false, + // `annotation: true` appends the sourceMappingURL to the end of + // the css file, helping the browser find the sourcemap + annotation: true, + } + : false, + minimizerOptions: { preset: ['default', { minifyFontValues: { removeQuotes: false } }], }, }), diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json index 6fddb9d8e40..d10fd466cb1 100644 --- a/packages/react-scripts/package.json +++ b/packages/react-scripts/package.json @@ -42,6 +42,7 @@ "camelcase": "^6.1.0", "case-sensitive-paths-webpack-plugin": "2.3.0", "css-loader": "4.3.0", + "css-minimizer-webpack-plugin": "1.1.5", "dotenv": "8.2.0", "dotenv-expand": "5.1.0", "eslint": "^7.11.0", @@ -63,14 +64,12 @@ "jest-resolve": "26.6.0", "jest-watch-typeahead": "0.6.1", "mini-css-extract-plugin": "0.11.3", - "optimize-css-assets-webpack-plugin": "5.0.4", "pnp-webpack-plugin": "1.6.4", "postcss": "8.2.4", "postcss-flexbugs-fixes": "5.0.2", "postcss-loader": "4.2.0", "postcss-normalize": "9.0.0", "postcss-preset-env": "6.7.0", - "postcss-safe-parser": "5.0.2", "prompts": "2.4.0", "react-app-polyfill": "^2.0.0", "react-dev-utils": "^11.0.3", From fb56a142b73246a0d13d5cfaf2bf3a72cf85964f Mon Sep 17 00:00:00 2001 From: jasonwilliams Date: Fri, 20 Nov 2020 19:21:45 +0000 Subject: [PATCH 07/59] Add support for Webpack 5 message objects --- packages/react-dev-utils/formatWebpackMessages.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/react-dev-utils/formatWebpackMessages.js b/packages/react-dev-utils/formatWebpackMessages.js index f459ea98ccc..7f7ec3bcdff 100644 --- a/packages/react-dev-utils/formatWebpackMessages.js +++ b/packages/react-dev-utils/formatWebpackMessages.js @@ -15,7 +15,19 @@ function isLikelyASyntaxError(message) { // Cleans up webpack error messages. function formatMessage(message) { - let lines = message.split('\n'); + let lines = []; + + if (typeof message === 'string') { + lines = message.split('\n'); + } else if ('message' in message) { + lines = message['message'].split('\n'); + } else if (Array.isArray(message)) { + message.forEach(message => { + if ('message' in message) { + lines = message['message'].split('\n'); + } + }); + } // Strip webpack-added headers off errors/warnings // https://github.com/webpack/webpack/blob/master/lib/ModuleError.js From 48c545611eb30f78b9e04b4b748eb240fa06bb12 Mon Sep 17 00:00:00 2001 From: "Morten N.O. Henriksen" Date: Sat, 5 Dec 2020 11:39:49 +0100 Subject: [PATCH 08/59] Update WebpackManifestPlugin to v3.0.0 --- packages/react-scripts/config/webpack.config.js | 4 ++-- packages/react-scripts/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/react-scripts/config/webpack.config.js b/packages/react-scripts/config/webpack.config.js index b7fd81e5906..5036271d900 100644 --- a/packages/react-scripts/config/webpack.config.js +++ b/packages/react-scripts/config/webpack.config.js @@ -19,7 +19,7 @@ const InlineChunkHtmlPlugin = require('react-dev-utils/InlineChunkHtmlPlugin'); const TerserPlugin = require('terser-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); -const ManifestPlugin = require('webpack-manifest-plugin'); +const { WebpackManifestPlugin } = require('webpack-manifest-plugin'); const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin'); const WorkboxWebpackPlugin = require('workbox-webpack-plugin'); const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin'); @@ -680,7 +680,7 @@ module.exports = function (webpackEnv) { // `index.html` // - "entrypoints" key: Array of files which are included in `index.html`, // can be used to reconstruct the HTML if necessary - new ManifestPlugin({ + new WebpackManifestPlugin({ fileName: 'asset-manifest.json', publicPath: paths.publicUrlOrPath, generate: (seed, files, entrypoints) => { diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json index d10fd466cb1..cbfe4c674b9 100644 --- a/packages/react-scripts/package.json +++ b/packages/react-scripts/package.json @@ -84,7 +84,7 @@ "url-loader": "4.1.1", "webpack": "4.44.2", "webpack-dev-server": "3.11.1", - "webpack-manifest-plugin": "2.2.0", + "webpack-manifest-plugin": "3.0.0", "workbox-webpack-plugin": "5.1.4" }, "devDependencies": { From 468ffe688433e9bc72a30d4cb015b57ad26daa8e Mon Sep 17 00:00:00 2001 From: "Morten N.O. Henriksen" Date: Sat, 5 Dec 2020 13:28:23 +0100 Subject: [PATCH 09/59] Support both "SingleEntryPlugin" and "EntryPlugin" --- packages/react-dev-utils/ModuleNotFoundPlugin.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/react-dev-utils/ModuleNotFoundPlugin.js b/packages/react-dev-utils/ModuleNotFoundPlugin.js index 55705fd3ea9..5977707c569 100644 --- a/packages/react-dev-utils/ModuleNotFoundPlugin.js +++ b/packages/react-dev-utils/ModuleNotFoundPlugin.js @@ -100,8 +100,13 @@ class ModuleNotFoundPlugin { const { prettierError } = this; compiler.hooks.make.intercept({ register(tap) { + // "SingleEntryPlugin" can be removed when Webpack 4 no longer have to be supported if ( - !(tap.name === 'MultiEntryPlugin' || tap.name === 'SingleEntryPlugin') + !( + tap.name === 'MultiEntryPlugin' || + tap.name === 'SingleEntryPlugin' || + tap.name === 'EntryPlugin' + ) ) { return tap; } From 4d0be4a674300c43d476508166440a7cec0f58f7 Mon Sep 17 00:00:00 2001 From: "Morten N.O. Henriksen" Date: Sat, 6 Mar 2021 08:37:37 +0100 Subject: [PATCH 10/59] Support Webpack 5 IgnorePlugin signature Reference: * https://webpack.js.org/plugins/ignore-plugin/#example-of-ignoring-moment-locales * #10006 --- packages/react-scripts/config/webpack.config.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/react-scripts/config/webpack.config.js b/packages/react-scripts/config/webpack.config.js index 5036271d900..24956406cd2 100644 --- a/packages/react-scripts/config/webpack.config.js +++ b/packages/react-scripts/config/webpack.config.js @@ -703,7 +703,10 @@ module.exports = function (webpackEnv) { // solution that requires the user to opt into importing specific locales. // https://github.com/jmblog/how-to-optimize-momentjs-with-webpack // You can remove this if you don't use Moment.js: - new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/), + new webpack.IgnorePlugin({ + resourceRegExp: /^\.\/locale$/, + contextRegExp: /moment$/, + }), // Generate a service worker script that will precache, and keep up to date, // the HTML & assets that are part of the webpack build. isEnvProduction && From cfee807a76aa8263c46fff785b4a1ceba9374715 Mon Sep 17 00:00:00 2001 From: "Morten N.O. Henriksen" Date: Sat, 6 Mar 2021 09:41:30 +0100 Subject: [PATCH 11/59] Update webpack and dev server --- packages/react-error-overlay/package.json | 5 +- .../react-scripts/config/webpack.config.js | 78 +++------------- .../config/webpackDevServer.config.js | 93 +++++++++---------- packages/react-scripts/package.json | 36 ++++--- 4 files changed, 74 insertions(+), 138 deletions(-) diff --git a/packages/react-error-overlay/package.json b/packages/react-error-overlay/package.json index 137ceb7f266..a1d031af960 100644 --- a/packages/react-error-overlay/package.json +++ b/packages/react-error-overlay/package.json @@ -65,9 +65,8 @@ "react-dom": "^17.0.1", "rimraf": "^3.0.2", "settle-promise": "1.0.0", - "source-map": "0.5.7", - "terser-webpack-plugin": "4.2.3", - "webpack": "^4.44.2" + "source-map": "0.7.3", + "webpack": "^5.24.3" }, "jest": { "setupFiles": [ diff --git a/packages/react-scripts/config/webpack.config.js b/packages/react-scripts/config/webpack.config.js index 24956406cd2..eb5f6e45ed4 100644 --- a/packages/react-scripts/config/webpack.config.js +++ b/packages/react-scripts/config/webpack.config.js @@ -12,7 +12,6 @@ const fs = require('fs'); const path = require('path'); const webpack = require('webpack'); const resolve = require('resolve'); -const PnpWebpackPlugin = require('pnp-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin'); const InlineChunkHtmlPlugin = require('react-dev-utils/InlineChunkHtmlPlugin'); @@ -167,6 +166,7 @@ module.exports = function (webpackEnv) { }; return { + target: ['browserslist'], mode: isEnvProduction ? 'production' : isEnvDevelopment && 'development', // Stop compilation early in production bail: isEnvProduction, @@ -212,8 +212,6 @@ module.exports = function (webpackEnv) { filename: isEnvProduction ? 'static/js/[name].[contenthash:8].js' : isEnvDevelopment && 'static/js/bundle.js', - // TODO: remove this when upgrading to webpack 5 - futureEmitAssets: true, // There are also additional JS chunk files if you use code splitting. chunkFilename: isEnvProduction ? 'static/js/[name].[contenthash:8].chunk.js' @@ -230,13 +228,13 @@ module.exports = function (webpackEnv) { .replace(/\\/g, '/') : isEnvDevelopment && (info => path.resolve(info.absoluteResourcePath).replace(/\\/g, '/')), - // Prevents conflicts when multiple webpack runtimes (from different apps) - // are used on the same page. - jsonpFunction: `webpackJsonp${appPackageJson.name}`, // this defaults to 'window', but by setting it to 'this' then // module chunks which are built will work in web workers as well. globalObject: 'this', }, + infrastructureLogging: { + level: 'none', + }, optimization: { minimize: isEnvProduction, minimizer: [ @@ -279,38 +277,10 @@ module.exports = function (webpackEnv) { ascii_only: true, }, }, - sourceMap: shouldUseSourceMap, }), // This is only used in production mode - new CssMinimizerPlugin({ - sourceMap: shouldUseSourceMap - ? { - // `inline: false` forces the sourcemap to be output into a - // separate file - inline: false, - // `annotation: true` appends the sourceMappingURL to the end of - // the css file, helping the browser find the sourcemap - annotation: true, - } - : false, - minimizerOptions: { - preset: ['default', { minifyFontValues: { removeQuotes: false } }], - }, - }), + new CssMinimizerPlugin(), ], - // Automatically split vendor and commons - // https://twitter.com/wSokra/status/969633336732905474 - // https://medium.com/webpack/webpack-4-code-splitting-chunk-graph-and-the-splitchunks-optimization-be739a861366 - splitChunks: { - chunks: 'all', - name: isEnvDevelopment, - }, - // Keep the runtime chunk separated to enable long term caching - // https://twitter.com/wSokra/status/969679223278505985 - // https://github.com/facebook/create-react-app/issues/5358 - runtimeChunk: { - name: entrypoint => `runtime-${entrypoint.name}`, - }, }, resolve: { // This allows you to set a fallback for where webpack should look for modules. @@ -341,9 +311,6 @@ module.exports = function (webpackEnv) { ...(modules.webpackAliases || {}), }, plugins: [ - // Adds support for installing with Plug'n'Play, leading to faster installs and adding - // guards against forgotten dependencies and such. - PnpWebpackPlugin, // Prevents users from importing files from outside of src/ (or node_modules/). // This often causes confusion because we only process files within src/ with babel. // To fix this, we prevent you from importing files out of src/ -- if you'd like to, @@ -355,13 +322,6 @@ module.exports = function (webpackEnv) { ]), ], }, - resolveLoader: { - plugins: [ - // Also related to Plug'n'Play, but this time it tells webpack to load its loaders - // from the current package. - PnpWebpackPlugin.moduleLoader(module), - ], - }, module: { strictExportPresence: true, rules: [ @@ -753,15 +713,15 @@ module.exports = function (webpackEnv) { // '../cra-template-typescript/template/src/App.tsx' // otherwise. include: [ - '../**/src/**/*.{ts,tsx}', - '**/src/**/*.{ts,tsx}', - ].map(file => ({ file })), + { file: '../**/src/**/*.{ts,tsx}' }, + { file: '**/src/**/*.{ts,tsx}' }, + ], exclude: [ - '**/src/**/__tests__/**', - '**/src/**/?(*.)(spec|test).*', - '**/src/setupProxy.*', - '**/src/setupTests.*', - ].map(file => ({ file })), + { file: '**/src/**/__tests__/**' }, + { file: '**/src/**/?(*.){spec|test}.*' }, + { file: '**/src/setupProxy.*' }, + { file: '**/src/setupTests.*' }, + ], }, logger: { infrastructure: 'silent', @@ -793,18 +753,6 @@ module.exports = function (webpackEnv) { }, }), ].filter(Boolean), - // Some libraries import Node modules but don't use them in the browser. - // Tell webpack to provide empty mocks for them so importing them works. - node: { - module: 'empty', - dgram: 'empty', - dns: 'mock', - fs: 'empty', - http2: 'empty', - net: 'empty', - tls: 'empty', - child_process: 'empty', - }, // Turn off performance processing because we utilize // our own hints via the FileSizeReporter performance: false, diff --git a/packages/react-scripts/config/webpackDevServer.config.js b/packages/react-scripts/config/webpackDevServer.config.js index bf8c98d0d91..df50f81bdf0 100644 --- a/packages/react-scripts/config/webpackDevServer.config.js +++ b/packages/react-scripts/config/webpackDevServer.config.js @@ -23,6 +23,8 @@ const sockPath = process.env.WDS_SOCKET_PATH; // default: '/sockjs-node' const sockPort = process.env.WDS_SOCKET_PORT; module.exports = function (proxy, allowedHost) { + const disableFirewall = + !proxy || process.env.DANGEROUSLY_DISABLE_HOST_CHECK === 'true'; return { // WebpackDevServer 2.4.3 introduced a security fix that prevents remote // websites from potentially accessing local content through DNS rebinding: @@ -40,64 +42,54 @@ module.exports = function (proxy, allowedHost) { // So we will disable the host check normally, but enable it if you have // specified the `proxy` setting. Finally, we let you override it if you // really know what you're doing with a special environment variable. - disableHostCheck: - !proxy || process.env.DANGEROUSLY_DISABLE_HOST_CHECK === 'true', + // Note: ["localhost", ".localhost"] will support subdomains - but we might + // want to allow setting the allowedHosts manually for more complex setups + firewall: disableFirewall ? false : [allowedHost], // Enable gzip compression of generated files. compress: true, - // Silence WebpackDevServer's own logs since they're generally not useful. - // It will still show compile warnings and errors with this setting. - clientLogLevel: 'none', - // By default WebpackDevServer serves physical files from current directory - // in addition to all the virtual build products that it serves from memory. - // This is confusing because those files won’t automatically be available in - // production build folder unless we copy them. However, copying the whole - // project directory is dangerous because we may expose sensitive files. - // Instead, we establish a convention that only files in `public` directory - // get served. Our build script will copy `public` into the `build` folder. - // In `index.html`, you can get URL of `public` folder with %PUBLIC_URL%: - // - // In JavaScript code, you can access it with `process.env.PUBLIC_URL`. - // Note that we only recommend to use `public` folder as an escape hatch - // for files like `favicon.ico`, `manifest.json`, and libraries that are - // for some reason broken when imported through webpack. If you just want to - // use an image, put it in `src` and `import` it from JavaScript instead. - contentBase: paths.appPublic, - contentBasePublicPath: paths.publicUrlOrPath, - // By default files from `contentBase` will not trigger a page reload. - watchContentBase: true, - // Enable hot reloading server. It will provide WDS_SOCKET_PATH endpoint - // for the WebpackDevServer client so it can learn when the files were - // updated. The WebpackDevServer client is included as an entry point - // in the webpack development configuration. Note that only changes - // to CSS are currently hot reloaded. JS changes will refresh the browser. - hot: true, - // Use 'ws' instead of 'sockjs-node' on server since we're using native - // websockets in `webpackHotDevClient`. - transportMode: 'ws', + static: { + // By default WebpackDevServer serves physical files from current directory + // in addition to all the virtual build products that it serves from memory. + // This is confusing because those files won’t automatically be available in + // production build folder unless we copy them. However, copying the whole + // project directory is dangerous because we may expose sensitive files. + // Instead, we establish a convention that only files in `public` directory + // get served. Our build script will copy `public` into the `build` folder. + // In `index.html`, you can get URL of `public` folder with %PUBLIC_URL%: + // + // In JavaScript code, you can access it with `process.env.PUBLIC_URL`. + // Note that we only recommend to use `public` folder as an escape hatch + // for files like `favicon.ico`, `manifest.json`, and libraries that are + // for some reason broken when imported through webpack. If you just want to + // use an image, put it in `src` and `import` it from JavaScript instead. + directory: paths.appPublic, + publicPath: [paths.publicUrlOrPath], + // By default files from `contentBase` will not trigger a page reload. + watch: { + // Reportedly, this avoids CPU overload on some systems. + // https://github.com/facebook/create-react-app/issues/293 + // src/node_modules is not ignored to support absolute imports + // https://github.com/facebook/create-react-app/issues/1065 + ignored: ignoredFiles(paths.appSrc), + }, + }, // Prevent a WS client from getting injected as we're already including // `webpackHotDevClient`. injectClient: false, - // Enable custom sockjs pathname for websocket connection to hot reloading server. - // Enable custom sockjs hostname, pathname and port for websocket connection - // to hot reloading server. - sockHost, - sockPath, - sockPort, + client: { + // Enable custom sockjs pathname for websocket connection to hot reloading server. + // Enable custom sockjs hostname, pathname and port for websocket connection + // to hot reloading server. + host: sockHost, + path: sockPath, + port: sockPort, + }, // It is important to tell WebpackDevServer to use the same "publicPath" path as // we specified in the webpack config. When homepage is '.', default to serving // from the root. // remove last slash so user can land on `/test` instead of `/test/` publicPath: paths.publicUrlOrPath.slice(0, -1), - // WebpackDevServer is noisy by default so we emit custom message instead - // by listening to the compiler events with `compiler.hooks[...].tap` calls above. - quiet: true, - // Reportedly, this avoids CPU overload on some systems. - // https://github.com/facebook/create-react-app/issues/293 - // src/node_modules is not ignored to support absolute imports - // https://github.com/facebook/create-react-app/issues/1065 - watchOptions: { - ignored: ignoredFiles(paths.appSrc), - }, + https: getHttpsConfig(), host, overlay: false, @@ -107,10 +99,9 @@ module.exports = function (proxy, allowedHost) { disableDotRule: true, index: paths.publicUrlOrPath, }, - public: allowedHost, // `proxy` is run between `before` and `after` `webpack-dev-server` hooks proxy, - before(app, server) { + onBeforeSetupMiddleware(app, server) { // Keep `evalSourceMapMiddleware` and `errorOverlayMiddleware` // middlewares before `redirectServedPath` otherwise will not have any effect // This lets us fetch source contents from webpack for the error overlay @@ -123,7 +114,7 @@ module.exports = function (proxy, allowedHost) { require(paths.proxySetup)(app); } }, - after(app) { + onAfterSetupMiddleware(app) { // Redirect to `PUBLIC_URL` or `homepage` from `package.json` if url not match app.use(redirectServedPath(paths.publicUrlOrPath)); diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json index cbfe4c674b9..0fd8c79a7e1 100644 --- a/packages/react-scripts/package.json +++ b/packages/react-scripts/package.json @@ -28,8 +28,8 @@ }, "types": "./lib/react-app.d.ts", "dependencies": { - "@babel/core": "7.12.3", - "@pmmmwh/react-refresh-webpack-plugin": "0.4.3", + "@babel/core": "7.13.8", + "@pmmmwh/react-refresh-webpack-plugin": "0.5.0-beta.1", "@svgr/webpack": "5.5.0", "@typescript-eslint/eslint-plugin": "^4.5.0", "@typescript-eslint/parser": "^4.5.0", @@ -40,9 +40,9 @@ "babel-preset-react-app": "^10.0.0", "bfj": "^7.0.2", "camelcase": "^6.1.0", - "case-sensitive-paths-webpack-plugin": "2.3.0", - "css-loader": "4.3.0", - "css-minimizer-webpack-plugin": "1.1.5", + "case-sensitive-paths-webpack-plugin": "2.4.0", + "css-loader": "5.1.1", + "css-minimizer-webpack-plugin": "1.2.0", "dotenv": "8.2.0", "dotenv-expand": "5.1.0", "eslint": "^7.11.0", @@ -55,35 +55,33 @@ "eslint-plugin-react-hooks": "^4.2.0", "eslint-plugin-testing-library": "^3.9.2", "eslint-webpack-plugin": "^2.5.2", - "file-loader": "6.1.1", + "file-loader": "6.2.0", "fs-extra": "^9.0.1", - "html-webpack-plugin": "4.5.0", + "html-webpack-plugin": "5.2.0", "identity-obj-proxy": "3.0.0", "jest": "26.6.0", "jest-circus": "26.6.0", "jest-resolve": "26.6.0", "jest-watch-typeahead": "0.6.1", - "mini-css-extract-plugin": "0.11.3", - "pnp-webpack-plugin": "1.6.4", - "postcss": "8.2.4", + "mini-css-extract-plugin": "1.3.9", + "postcss": "8.2.7", "postcss-flexbugs-fixes": "5.0.2", - "postcss-loader": "4.2.0", + "postcss-loader": "5.1.0", "postcss-normalize": "9.0.0", "postcss-preset-env": "6.7.0", "prompts": "2.4.0", "react-app-polyfill": "^2.0.0", "react-dev-utils": "^11.0.3", - "react-refresh": "^0.8.3", - "resolve": "1.18.1", + "react-refresh": "^0.9.0", + "resolve": "1.20.0", "resolve-url-loader": "^3.1.2", - "sass-loader": "^10.0.5", - "semver": "7.3.2", - "style-loader": "1.3.0", - "terser-webpack-plugin": "4.2.3", + "sass-loader": "^11.0.1", + "semver": "7.3.4", + "style-loader": "2.0.0", "ts-pnp": "1.2.0", "url-loader": "4.1.1", - "webpack": "4.44.2", - "webpack-dev-server": "3.11.1", + "webpack": "5.24.3", + "webpack-dev-server": "4.0.0-beta.0", "webpack-manifest-plugin": "3.0.0", "workbox-webpack-plugin": "5.1.4" }, From 38d72e71461d885fb743fb1fc253bf4de0437079 Mon Sep 17 00:00:00 2001 From: "Morten N.O. Henriksen" Date: Sat, 6 Mar 2021 10:10:08 +0100 Subject: [PATCH 12/59] Enable persistent cache --- packages/react-scripts/config/paths.js | 3 +++ packages/react-scripts/config/webpack.config.js | 16 ++++++++++++++-- .../persistentCache/createEnvironmentHash.js | 9 +++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 packages/react-scripts/config/webpack/persistentCache/createEnvironmentHash.js diff --git a/packages/react-scripts/config/paths.js b/packages/react-scripts/config/paths.js index 67ba927fc80..c7d434d706e 100644 --- a/packages/react-scripts/config/paths.js +++ b/packages/react-scripts/config/paths.js @@ -74,6 +74,7 @@ module.exports = { testsSetup: resolveModule(resolveApp, 'src/setupTests'), proxySetup: resolveApp('src/setupProxy.js'), appNodeModules: resolveApp('node_modules'), + appWebpackCache: resolveApp('node_modules/.cache'), swSrc: resolveModule(resolveApp, 'src/service-worker'), publicUrlOrPath, }; @@ -97,6 +98,7 @@ module.exports = { testsSetup: resolveModule(resolveApp, 'src/setupTests'), proxySetup: resolveApp('src/setupProxy.js'), appNodeModules: resolveApp('node_modules'), + appWebpackCache: resolveApp('node_modules/.cache'), swSrc: resolveModule(resolveApp, 'src/service-worker'), publicUrlOrPath, // These properties only exist before ejecting: @@ -133,6 +135,7 @@ if ( testsSetup: resolveModule(resolveOwn, `${templatePath}/src/setupTests`), proxySetup: resolveOwn(`${templatePath}/src/setupProxy.js`), appNodeModules: resolveOwn('node_modules'), + appWebpackCache: resolveOwn('node_modules/.cache'), swSrc: resolveModule(resolveOwn, `${templatePath}/src/service-worker`), publicUrlOrPath, // These properties only exist before ejecting: diff --git a/packages/react-scripts/config/webpack.config.js b/packages/react-scripts/config/webpack.config.js index eb5f6e45ed4..6890b3140c1 100644 --- a/packages/react-scripts/config/webpack.config.js +++ b/packages/react-scripts/config/webpack.config.js @@ -35,8 +35,7 @@ const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin' const getCacheIdentifier = require('react-dev-utils/getCacheIdentifier'); // @remove-on-eject-end const postcssNormalize = require('postcss-normalize'); - -const appPackageJson = require(paths.appPackageJson); +const createEnvironmentHash = require('./webpack/persistentCache/createEnvironmentHash'); // Source maps are resource heavy and can cause out of memory issue for large source files. const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false'; @@ -232,6 +231,19 @@ module.exports = function (webpackEnv) { // module chunks which are built will work in web workers as well. globalObject: 'this', }, + cache: { + type: 'filesystem', + version: createEnvironmentHash(env.raw), + cacheDirectory: paths.appWebpackCache, + store: 'pack', + buildDependencies: { + defaultWebpack: ['webpack/lib/'], + config: [__filename], + tsconfig: [paths.appTsConfig, paths.appJsConfig].filter(f => + fs.existsSync(f) + ), + }, + }, infrastructureLogging: { level: 'none', }, diff --git a/packages/react-scripts/config/webpack/persistentCache/createEnvironmentHash.js b/packages/react-scripts/config/webpack/persistentCache/createEnvironmentHash.js new file mode 100644 index 00000000000..c59bb793ff6 --- /dev/null +++ b/packages/react-scripts/config/webpack/persistentCache/createEnvironmentHash.js @@ -0,0 +1,9 @@ +'use strict'; +const { createHash } = require('crypto'); + +module.exports = env => { + const hash = createHash('md4'); + hash.update(JSON.stringify(env)); + + return hash.digest('hex'); +}; From 5bef914dc71a6c9f0fa2d2b54a25f3257faa4a95 Mon Sep 17 00:00:00 2001 From: "Morten N.O. Henriksen" Date: Sat, 6 Mar 2021 10:12:59 +0100 Subject: [PATCH 13/59] Fix react-error-overlay webpack --- packages/react-error-overlay/webpack.config.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/react-error-overlay/webpack.config.js b/packages/react-error-overlay/webpack.config.js index dce51e0f9e9..82dec77be5b 100644 --- a/packages/react-error-overlay/webpack.config.js +++ b/packages/react-error-overlay/webpack.config.js @@ -34,14 +34,14 @@ module.exports = { alias: { iframeScript$: path.resolve(__dirname, './lib/iframe-bundle.js'), }, + fallback: { + fs: false, + path: false, + }, }, optimization: { nodeEnv: false, }, - node: { - fs: 'empty', - process: false, - }, performance: { hints: false, }, From 58d36c2481730a0d0837cc3cf9d3ce551988b0cd Mon Sep 17 00:00:00 2001 From: "Morten N.O. Henriksen" Date: Sat, 6 Mar 2021 11:32:12 +0100 Subject: [PATCH 14/59] Fix dev server config --- .../react-scripts/config/webpackDevServer.config.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/react-scripts/config/webpackDevServer.config.js b/packages/react-scripts/config/webpackDevServer.config.js index df50f81bdf0..68c3081d436 100644 --- a/packages/react-scripts/config/webpackDevServer.config.js +++ b/packages/react-scripts/config/webpackDevServer.config.js @@ -84,11 +84,13 @@ module.exports = function (proxy, allowedHost) { path: sockPath, port: sockPort, }, - // It is important to tell WebpackDevServer to use the same "publicPath" path as - // we specified in the webpack config. When homepage is '.', default to serving - // from the root. - // remove last slash so user can land on `/test` instead of `/test/` - publicPath: paths.publicUrlOrPath.slice(0, -1), + dev: { + // It is important to tell WebpackDevServer to use the same "publicPath" path as + // we specified in the webpack config. When homepage is '.', default to serving + // from the root. + // remove last slash so user can land on `/test` instead of `/test/` + publicPath: paths.publicUrlOrPath.slice(0, -1), + }, https: getHttpsConfig(), host, From a89a63a07b42b284a76fa75771881dfc64b44b38 Mon Sep 17 00:00:00 2001 From: "Morten N.O. Henriksen" Date: Sat, 6 Mar 2021 11:32:33 +0100 Subject: [PATCH 15/59] Remove support for SingleEntryPlugin --- packages/react-dev-utils/ModuleNotFoundPlugin.js | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/packages/react-dev-utils/ModuleNotFoundPlugin.js b/packages/react-dev-utils/ModuleNotFoundPlugin.js index 5977707c569..da8eed0186c 100644 --- a/packages/react-dev-utils/ModuleNotFoundPlugin.js +++ b/packages/react-dev-utils/ModuleNotFoundPlugin.js @@ -100,14 +100,7 @@ class ModuleNotFoundPlugin { const { prettierError } = this; compiler.hooks.make.intercept({ register(tap) { - // "SingleEntryPlugin" can be removed when Webpack 4 no longer have to be supported - if ( - !( - tap.name === 'MultiEntryPlugin' || - tap.name === 'SingleEntryPlugin' || - tap.name === 'EntryPlugin' - ) - ) { + if (!(tap.name === 'MultiEntryPlugin' || tap.name === 'EntryPlugin')) { return tap; } return Object.assign({}, tap, { From 74ed0c7d10e78c125dd5543421a3a916e37bfa0c Mon Sep 17 00:00:00 2001 From: "Morten N.O. Henriksen" Date: Sat, 6 Mar 2021 11:33:06 +0100 Subject: [PATCH 16/59] update workbox-webpack-plugin --- packages/react-scripts/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json index 0fd8c79a7e1..cc7b78949d3 100644 --- a/packages/react-scripts/package.json +++ b/packages/react-scripts/package.json @@ -83,7 +83,7 @@ "webpack": "5.24.3", "webpack-dev-server": "4.0.0-beta.0", "webpack-manifest-plugin": "3.0.0", - "workbox-webpack-plugin": "5.1.4" + "workbox-webpack-plugin": "6.1.1" }, "devDependencies": { "react": "^17.0.1", From 19faf8cb89c6a9aed7bf4d14b6f7c12304ae3f74 Mon Sep 17 00:00:00 2001 From: "Morten N.O. Henriksen" Date: Sat, 6 Mar 2021 11:35:37 +0100 Subject: [PATCH 17/59] Fix post css config --- .../react-scripts/config/webpack.config.js | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/packages/react-scripts/config/webpack.config.js b/packages/react-scripts/config/webpack.config.js index 6890b3140c1..bf1829b032e 100644 --- a/packages/react-scripts/config/webpack.config.js +++ b/packages/react-scripts/config/webpack.config.js @@ -34,7 +34,6 @@ const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin' // @remove-on-eject-begin const getCacheIdentifier = require('react-dev-utils/getCacheIdentifier'); // @remove-on-eject-end -const postcssNormalize = require('postcss-normalize'); const createEnvironmentHash = require('./webpack/persistentCache/createEnvironmentHash'); // Source maps are resource heavy and can cause out of memory issue for large source files. @@ -124,22 +123,27 @@ module.exports = function (webpackEnv) { // package.json loader: require.resolve('postcss-loader'), options: { - // Necessary for external CSS imports to work - // https://github.com/facebook/create-react-app/issues/2677 - ident: 'postcss', - plugins: () => [ - require('postcss-flexbugs-fixes'), - require('postcss-preset-env')({ - autoprefixer: { - flexbox: 'no-2009', - }, - stage: 3, - }), - // Adds PostCSS Normalize as the reset css with default options, - // so that it honors browserslist config in package.json - // which in turn let's users customize the target behavior as per their needs. - postcssNormalize(), - ], + postcssOptions: { + // Necessary for external CSS imports to work + // https://github.com/facebook/create-react-app/issues/2677 + ident: 'postcss', + plugins: [ + 'postcss-flexbugs-fixes', + [ + 'postcss-preset-env', + { + autoprefixer: { + flexbox: 'no-2009', + }, + stage: 3, + }, + ], + // Adds PostCSS Normalize as the reset css with default options, + // so that it honors browserslist config in package.json + // which in turn let's users customize the target behavior as per their needs. + 'postcss-normalize', + ], + }, sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment, }, }, From bbf93d298fecd45a1794e4464f10d659e5aa06ff Mon Sep 17 00:00:00 2001 From: "Morten N.O. Henriksen" Date: Sat, 6 Mar 2021 11:36:02 +0100 Subject: [PATCH 18/59] Comment out WebpackManifestPlugin for now having issues with undefined path --- packages/react-scripts/config/webpack.config.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/react-scripts/config/webpack.config.js b/packages/react-scripts/config/webpack.config.js index bf1829b032e..19ef9df86a1 100644 --- a/packages/react-scripts/config/webpack.config.js +++ b/packages/react-scripts/config/webpack.config.js @@ -18,7 +18,7 @@ const InlineChunkHtmlPlugin = require('react-dev-utils/InlineChunkHtmlPlugin'); const TerserPlugin = require('terser-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); -const { WebpackManifestPlugin } = require('webpack-manifest-plugin'); +// const { WebpackManifestPlugin } = require('webpack-manifest-plugin'); const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin'); const WorkboxWebpackPlugin = require('workbox-webpack-plugin'); const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin'); @@ -656,7 +656,7 @@ module.exports = function (webpackEnv) { // `index.html` // - "entrypoints" key: Array of files which are included in `index.html`, // can be used to reconstruct the HTML if necessary - new WebpackManifestPlugin({ + /*new WebpackManifestPlugin({ fileName: 'asset-manifest.json', publicPath: paths.publicUrlOrPath, generate: (seed, files, entrypoints) => { @@ -673,7 +673,7 @@ module.exports = function (webpackEnv) { entrypoints: entrypointFiles, }; }, - }), + }),*/ // 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. From 73c952bc24c700a3c84faefd0c66448a6b29a3c5 Mon Sep 17 00:00:00 2001 From: "Morten N.O. Henriksen" Date: Sat, 6 Mar 2021 11:36:27 +0100 Subject: [PATCH 19/59] Add fast refresh entries to ModuleScopePlugin --- packages/react-scripts/config/webpack.config.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/react-scripts/config/webpack.config.js b/packages/react-scripts/config/webpack.config.js index 19ef9df86a1..f4923822217 100644 --- a/packages/react-scripts/config/webpack.config.js +++ b/packages/react-scripts/config/webpack.config.js @@ -45,6 +45,10 @@ const webpackDevClientEntry = require.resolve( const reactRefreshOverlayEntry = require.resolve( 'react-dev-utils/refreshOverlayInterop' ); +const reactRefreshRuntimeEntry = require.resolve('react-refresh/runtime'); +const reactRefreshWebpackPluginRuntimeEntry = require.resolve( + '@pmmmwh/react-refresh-webpack-plugin/lib/runtime/RefreshUtils' +); // Some apps do not need the benefits of saving a web request, so not inlining the chunk // makes for a smoother build process. @@ -334,6 +338,8 @@ module.exports = function (webpackEnv) { // Make sure your source files are compiled, as they will not be processed in any way. new ModuleScopePlugin(paths.appSrc, [ paths.appPackageJson, + reactRefreshRuntimeEntry, + reactRefreshWebpackPluginRuntimeEntry, reactRefreshOverlayEntry, ]), ], From 33f90642420252a4550f9d6d956398f238727ba2 Mon Sep 17 00:00:00 2001 From: "Morten N.O. Henriksen" Date: Sat, 6 Mar 2021 21:29:06 +0100 Subject: [PATCH 20/59] Format files --- .../getTemplateInstallPackage.test.js | 18 +++++++++--------- .../scripts/utils/verifyTypeScriptSetup.js | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/create-react-app/__tests__/getTemplateInstallPackage.test.js b/packages/create-react-app/__tests__/getTemplateInstallPackage.test.js index bef6106a7e1..5e0f46e028d 100644 --- a/packages/create-react-app/__tests__/getTemplateInstallPackage.test.js +++ b/packages/create-react-app/__tests__/getTemplateInstallPackage.test.js @@ -21,9 +21,9 @@ describe('getTemplateInstallPackage', () => { }); it('cra-template-typescript gives cra-template-typescript', async () => { - await expect(getTemplateInstallPackage('cra-template-typescript')).resolves.toBe( - 'cra-template-typescript' - ); + await expect( + getTemplateInstallPackage('cra-template-typescript') + ).resolves.toBe('cra-template-typescript'); }); it('typescript gives cra-template-typescript', async () => { @@ -45,9 +45,9 @@ describe('getTemplateInstallPackage', () => { }); it('cra-template-typescript@next gives cra-template-typescript@next', async () => { - await expect(getTemplateInstallPackage('cra-template-typescript@next')).resolves.toBe( - 'cra-template-typescript@next' - ); + await expect( + getTemplateInstallPackage('cra-template-typescript@next') + ).resolves.toBe('cra-template-typescript@next'); }); it('@iansu gives @iansu/cra-template', async () => { @@ -69,9 +69,9 @@ describe('getTemplateInstallPackage', () => { }); it('@iansu/cra-template-typescript@next gives @iansu/cra-template-typescript@next', async () => { - await expect(getTemplateInstallPackage('@iansu/cra-template-typescript@next')).resolves.toBe( - '@iansu/cra-template-typescript@next' - ); + await expect( + getTemplateInstallPackage('@iansu/cra-template-typescript@next') + ).resolves.toBe('@iansu/cra-template-typescript@next'); }); it('http://example.com/cra-template.tar.gz gives http://example.com/cra-template.tar.gz', async () => { diff --git a/packages/react-scripts/scripts/utils/verifyTypeScriptSetup.js b/packages/react-scripts/scripts/utils/verifyTypeScriptSetup.js index 949f34ab7d2..cdc2d77a880 100644 --- a/packages/react-scripts/scripts/utils/verifyTypeScriptSetup.js +++ b/packages/react-scripts/scripts/utils/verifyTypeScriptSetup.js @@ -218,7 +218,7 @@ function verifyTypeScriptSetup() { if (appTsConfig.compilerOptions == null) { appTsConfig.compilerOptions = {}; firstTimeSetup = true; - } + } for (const option of Object.keys(compilerOptions)) { const { parsedValue, value, suggested, reason } = compilerOptions[option]; From 5e79ffa09b530298f334a92771e36213c8f48365 Mon Sep 17 00:00:00 2001 From: "Morten N.O. Henriksen" Date: Sat, 6 Mar 2021 21:29:33 +0100 Subject: [PATCH 21/59] Remove unused variables in start command --- packages/react-scripts/scripts/start.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/packages/react-scripts/scripts/start.js b/packages/react-scripts/scripts/start.js index 4eb6ffdcf4e..7bf39b4ae8a 100644 --- a/packages/react-scripts/scripts/start.js +++ b/packages/react-scripts/scripts/start.js @@ -101,19 +101,12 @@ checkBrowsers(paths.appPath, isInteractive) const appName = require(paths.appPackageJson).name; const useTypeScript = fs.existsSync(paths.appTsConfig); - const tscCompileOnError = process.env.TSC_COMPILE_ON_ERROR === 'true'; const urls = prepareUrls( protocol, HOST, port, paths.publicUrlOrPath.slice(0, -1) ); - const devSocket = { - warnings: warnings => - devServer.sockWrite(devServer.sockets, 'warnings', warnings), - errors: errors => - devServer.sockWrite(devServer.sockets, 'errors', errors), - }; // Create a webpack compiler that is configured with custom messages. const compiler = createCompiler({ appName, From c0e4c4db576ecc13a3ab10d92c0b4035b397a803 Mon Sep 17 00:00:00 2001 From: "Morten N.O. Henriksen" Date: Sat, 6 Mar 2021 21:52:31 +0100 Subject: [PATCH 22/59] git ignore tsconfig.tsbuildinfo supporting incremental typescript builds --- packages/cra-template-typescript/template/gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/cra-template-typescript/template/gitignore b/packages/cra-template-typescript/template/gitignore index 4d29575de80..b9e4afe8638 100644 --- a/packages/cra-template-typescript/template/gitignore +++ b/packages/cra-template-typescript/template/gitignore @@ -5,6 +5,9 @@ /.pnp .pnp.js +# build cache info +tsconfig.tsbuildinfo + # testing /coverage From 871b2e915acd18206ac4199d9bbe487726368a8f Mon Sep 17 00:00:00 2001 From: "Morten N.O. Henriksen" Date: Sat, 20 Mar 2021 15:55:29 +0100 Subject: [PATCH 23/59] simplify output path review feedback from @kumarlachhani --- packages/react-scripts/config/webpack.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-scripts/config/webpack.config.js b/packages/react-scripts/config/webpack.config.js index f4923822217..cbd2bf5ee4c 100644 --- a/packages/react-scripts/config/webpack.config.js +++ b/packages/react-scripts/config/webpack.config.js @@ -211,7 +211,7 @@ module.exports = function (webpackEnv) { : paths.appIndexJs, output: { // The build folder. - path: isEnvProduction ? paths.appBuild : undefined, + path: paths.appBuild, // Add /* filename */ comments to generated require()s in the output. pathinfo: isEnvDevelopment, // There will be one main bundle, and one file per asynchronous chunk. From 613e2a57d14a96c43d57e9dd9ef898655d6afc64 Mon Sep 17 00:00:00 2001 From: "Morten N.O. Henriksen" Date: Sat, 20 Mar 2021 16:27:37 +0100 Subject: [PATCH 24/59] Use asset modules in react-scripts --- .../react-scripts/config/webpack.config.js | 32 ++++++++++++------- packages/react-scripts/package.json | 2 -- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/packages/react-scripts/config/webpack.config.js b/packages/react-scripts/config/webpack.config.js index cbd2bf5ee4c..7d0fa58c8bf 100644 --- a/packages/react-scripts/config/webpack.config.js +++ b/packages/react-scripts/config/webpack.config.js @@ -358,11 +358,15 @@ module.exports = function (webpackEnv) { // https://github.com/jshttp/mime-db { test: [/\.avif$/], - loader: require.resolve('url-loader'), - options: { - limit: imageInlineSizeLimit, - mimetype: 'image/avif', - name: 'static/media/[name].[hash:8].[ext]', + type: 'asset', + mimetype: 'image/avif', + generator: { + filename: 'static/media/[hash][ext][query]', + }, + parser: { + dataUrlCondition: { + maxSize: imageInlineSizeLimit, + }, }, }, // "url" loader works like "file" loader except that it embeds assets @@ -370,10 +374,14 @@ module.exports = function (webpackEnv) { // A missing `test` is equivalent to a match. { test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/], - loader: require.resolve('url-loader'), - options: { - limit: imageInlineSizeLimit, - name: 'static/media/[name].[hash:8].[ext]', + type: 'asset', + generator: { + filename: 'static/media/[hash][ext][query]', + }, + parser: { + dataUrlCondition: { + maxSize: imageInlineSizeLimit, + }, }, }, // Process application JS with Babel. @@ -558,14 +566,14 @@ module.exports = function (webpackEnv) { // This loader doesn't use a "test" so it will catch all modules // that fall through the other loaders. { - loader: require.resolve('file-loader'), // Exclude `js` files to keep "css" loader working as it injects // its runtime that would otherwise be processed through "file" loader. // Also exclude `html` and `json` extensions so they get processed // by webpacks internal loaders. exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/], - options: { - name: 'static/media/[name].[hash:8].[ext]', + type: 'asset/resource', + generator: { + filename: 'static/media/[hash][ext][query]', }, }, // ** STOP ** Are you adding a new loader? diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json index cc7b78949d3..bbfe6c5ee14 100644 --- a/packages/react-scripts/package.json +++ b/packages/react-scripts/package.json @@ -55,7 +55,6 @@ "eslint-plugin-react-hooks": "^4.2.0", "eslint-plugin-testing-library": "^3.9.2", "eslint-webpack-plugin": "^2.5.2", - "file-loader": "6.2.0", "fs-extra": "^9.0.1", "html-webpack-plugin": "5.2.0", "identity-obj-proxy": "3.0.0", @@ -79,7 +78,6 @@ "semver": "7.3.4", "style-loader": "2.0.0", "ts-pnp": "1.2.0", - "url-loader": "4.1.1", "webpack": "5.24.3", "webpack-dev-server": "4.0.0-beta.0", "webpack-manifest-plugin": "3.0.0", From 952f896dabcdaff3a526e38464292d8bbbdd2496 Mon Sep 17 00:00:00 2001 From: "Morten N.O. Henriksen" Date: Sat, 20 Mar 2021 16:27:52 +0100 Subject: [PATCH 25/59] Use asset modules in react-error-overlay --- packages/react-error-overlay/package.json | 1 - packages/react-error-overlay/webpack.config.js | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react-error-overlay/package.json b/packages/react-error-overlay/package.json index a1d031af960..defdc4fa498 100644 --- a/packages/react-error-overlay/package.json +++ b/packages/react-error-overlay/package.json @@ -59,7 +59,6 @@ "jest-fetch-mock": "2.1.2", "object-assign": "4.1.1", "promise": "8.1.0", - "raw-loader": "^4.0.2", "react": "^17.0.1", "react-app-polyfill": "^2.0.0", "react-dom": "^17.0.1", diff --git a/packages/react-error-overlay/webpack.config.js b/packages/react-error-overlay/webpack.config.js index 82dec77be5b..dc816b6f103 100644 --- a/packages/react-error-overlay/webpack.config.js +++ b/packages/react-error-overlay/webpack.config.js @@ -16,12 +16,13 @@ module.exports = { filename: 'index.js', library: 'ReactErrorOverlay', libraryTarget: 'umd', + assetModuleFilename: 'assets/[hash][ext][query]', }, module: { rules: [ { test: /iframe-bundle\.js$/, - use: 'raw-loader', + type: 'asset/source', }, { test: /\.js$/, From 651d0dba3f05e7e73e4baafc0741316c25b213a4 Mon Sep 17 00:00:00 2001 From: Joseph Atkins-Turkish Date: Wed, 12 May 2021 09:26:22 -0700 Subject: [PATCH 26/59] eslint-config-react-app typo fix (#10317) This just fixes a shell snippet in the readme file for this plugin --- packages/eslint-config-react-app/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eslint-config-react-app/README.md b/packages/eslint-config-react-app/README.md index 700e92aa777..52c5c390880 100644 --- a/packages/eslint-config-react-app/README.md +++ b/packages/eslint-config-react-app/README.md @@ -39,7 +39,7 @@ This config also ships with optional Jest rules for ESLint (based on [`eslint-pl You'll first need to add the ESLint plugin for Jest (if you don't already have it installed). ```sh -npm install --save-dev eslint-plugin-jest@^24.0.0 eslint-plugin-testing-library&^3.9.0 +npm install --save-dev eslint-plugin-jest@^24.0.0 eslint-plugin-testing-library@^3.9.0 ``` You can then enable these rules by adding the Jest config to the `extends` array in your ESLint config. From b680ee7c7a81786fae9a7d3bbe81d12ba19fef3a Mon Sep 17 00:00:00 2001 From: e-w-h <46170930+e-w-h@users.noreply.github.com> Date: Wed, 12 May 2021 12:30:25 -0400 Subject: [PATCH 27/59] Fix link address (#10907) Replace the Github home link with a link to the repo's main page or a link to the source (https://github.com/CodeByZach/pace/blob/master/pace.js) --- docusaurus/docs/using-the-public-folder.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docusaurus/docs/using-the-public-folder.md b/docusaurus/docs/using-the-public-folder.md index 71266db6f81..a33c3a29ec8 100644 --- a/docusaurus/docs/using-the-public-folder.md +++ b/docusaurus/docs/using-the-public-folder.md @@ -60,7 +60,7 @@ The `public` folder is useful as a workaround for a number of less common cases: - You need a file with a specific name in the build output, such as [`manifest.webmanifest`](https://developer.mozilla.org/en-US/docs/Web/Manifest). - You have thousands of images and need to dynamically reference their paths. -- You want to include a small script like [`pace.js`](https://github.hubspot.com/pace/docs/welcome/) outside of the bundled code. +- You want to include a small script like [`pace.js`](https://github.com/CodeByZach/pace) outside of the bundled code. - Some libraries may be incompatible with webpack and you have no other option but to include it as a `