From 2ea7648c371c4726d29239e732c0f2a363f76bd7 Mon Sep 17 00:00:00 2001 From: Aleksandr Sannikov Date: Tue, 14 Nov 2023 12:46:14 +0000 Subject: [PATCH 1/2] NO_JIRA: Extract and optimise JS Loaders --- .../config/loaders/getJSLoaders.js | 103 +++++++++++ .../react-scripts/config/webpack.config.js | 159 +---------------- .../config/webpack.config.ssr.js | 164 +----------------- 3 files changed, 119 insertions(+), 307 deletions(-) create mode 100644 packages/react-scripts/config/loaders/getJSLoaders.js diff --git a/packages/react-scripts/config/loaders/getJSLoaders.js b/packages/react-scripts/config/loaders/getJSLoaders.js new file mode 100644 index 0000000000..eb2ade03fc --- /dev/null +++ b/packages/react-scripts/config/loaders/getJSLoaders.js @@ -0,0 +1,103 @@ +'use strict'; + +const withIncludedPrefixes = require('../../backpack-addons/babelIncludePrefixes'); +const getCacheIdentifier = require('react-dev-utils/getCacheIdentifier'); + +function getJSLoaders( + isEnvProduction, + isEnvDevelopment, + shouldUseReactRefresh, + hasJsxRuntime, + shouldUseSourceMap +) { + return [ + // Process application JS with Babel. + // The preset includes JSX, Flow, TypeScript, and some ESnext features. + { + test: /\.(js|mjs|cjs|jsx|ts|tsx)$/, + include: withIncludedPrefixes(), // #backpack-addons babelIncludePrefixes + loader: require.resolve('babel-loader'), + options: { + customize: require.resolve('babel-preset-react-app/webpack-overrides'), + presets: [ + [ + require.resolve('babel-preset-react-app'), + { + runtime: hasJsxRuntime ? 'automatic' : 'classic', + }, + ], + ], + // @remove-on-eject-begin + babelrc: false, + configFile: false, + // Make sure we have a unique cache identifier, erring on the + // side of caution. + // We remove this when the user ejects because the default + // is sane and uses Babel options. Instead of options, we use + // the react-scripts and babel-preset-react-app versions. + cacheIdentifier: getCacheIdentifier( + isEnvProduction ? 'production' : isEnvDevelopment && 'development', + [ + 'babel-plugin-named-asset-import', + 'babel-preset-react-app', + 'react-dev-utils', + 'react-scripts', + ] + ), + // @remove-on-eject-end + plugins: [ + require.resolve('@loadable/babel-plugin'), + isEnvDevelopment && + shouldUseReactRefresh && + require.resolve('react-refresh/babel'), + ].filter(Boolean), + // This is a feature of `babel-loader` for webpack (not Babel itself). + // It enables caching results in ./node_modules/.cache/babel-loader/ + // directory for faster rebuilds. + cacheDirectory: true, + // See #6846 for context on why cacheCompression is disabled + cacheCompression: false, + compact: isEnvProduction, + }, + }, + { + test: /\.(js|mjs|cjs)$/, + exclude: [/@babel(?:\/|\\{1,2})runtime/, ...withIncludedPrefixes()], + loader: require.resolve('babel-loader'), + options: { + babelrc: false, + configFile: false, + compact: false, + presets: [ + [ + require.resolve('babel-preset-react-app/dependencies'), + { helpers: true }, + ], + ], + cacheDirectory: true, + // See #6846 for context on why cacheCompression is disabled + cacheCompression: false, + // @remove-on-eject-begin + cacheIdentifier: getCacheIdentifier( + isEnvProduction ? 'production' : isEnvDevelopment && 'development', + [ + 'babel-plugin-named-asset-import', + 'babel-preset-react-app', + 'react-dev-utils', + 'react-scripts', + ] + ), + // @remove-on-eject-end + // Babel sourcemaps are needed for debugging into node_modules + // code. Without the options below, debuggers like VSCode + // show incorrect code and set breakpoints on the wrong lines. + sourceMaps: shouldUseSourceMap, + inputSourceMap: shouldUseSourceMap, + }, + }, + ]; +} + +module.exports = { + getJSLoaders, +}; diff --git a/packages/react-scripts/config/webpack.config.js b/packages/react-scripts/config/webpack.config.js index b7323c73d1..b8ed670236 100644 --- a/packages/react-scripts/config/webpack.config.js +++ b/packages/react-scripts/config/webpack.config.js @@ -32,14 +32,12 @@ const ForkTsCheckerWebpackPlugin = ? require('react-dev-utils/ForkTsCheckerWarningWebpackPlugin') : require('react-dev-utils/ForkTsCheckerWebpackPlugin'); const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin'); -// @remove-on-eject-begin -const getCacheIdentifier = require('react-dev-utils/getCacheIdentifier'); -// @remove-on-eject-end const createEnvironmentHash = require('./webpack/persistentCache/createEnvironmentHash'); const isSsr = require('../backpack-addons/ssr/isSsr'); // #backpack-addons ssr const LoadablePlugin = require('@loadable/webpack-plugin'); +const { getJSLoaders } = require('./loaders/getJSLoaders'); // Source maps are resource heavy and can cause out of memory issue for large source files. const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false'; @@ -459,154 +457,13 @@ module.exports = function (webpackEnv) { }, // Process application JS with Babel. // The preset includes JSX, Flow, TypeScript, and some ESnext features. - { - test: /\.(js|mjs|cjs|jsx|ts|tsx)$/, - include: require('../backpack-addons/babelIncludePrefixes')(), // #backpack-addons babelIncludePrefixes - loader: require.resolve('babel-loader'), - options: { - customize: require.resolve( - 'babel-preset-react-app/webpack-overrides' - ), - presets: [ - [ - require.resolve('babel-preset-react-app'), - { - runtime: hasJsxRuntime ? 'automatic' : 'classic', - }, - ], - ], - // @remove-on-eject-begin - babelrc: false, - configFile: false, - // Make sure we have a unique cache identifier, erring on the - // side of caution. - // We remove this when the user ejects because the default - // is sane and uses Babel options. Instead of options, we use - // the react-scripts and babel-preset-react-app versions. - cacheIdentifier: getCacheIdentifier( - isEnvProduction - ? 'production' - : isEnvDevelopment && 'development', - [ - 'babel-plugin-named-asset-import', - 'babel-preset-react-app', - 'react-dev-utils', - 'react-scripts', - ] - ), - // @remove-on-eject-end - plugins: [ - require.resolve('@loadable/babel-plugin'), - isEnvDevelopment && - shouldUseReactRefresh && - require.resolve('react-refresh/babel'), - ].filter(Boolean), - // This is a feature of `babel-loader` for webpack (not Babel itself). - // It enables caching results in ./node_modules/.cache/babel-loader/ - // directory for faster rebuilds. - cacheDirectory: true, - // See #6846 for context on why cacheCompression is disabled - cacheCompression: false, - compact: isEnvProduction, - }, - }, - // TODO need extract to backpack-addons - // Process application JS with Babel but without `.storybook` folder. - // The preset includes JSX, Flow, TypeScript, and some ESnext features. - { - test: /\.(js|mjs|cjs|jsx|ts|tsx)$/, - exclude: /\.storybook/, - include: require('../backpack-addons/babelIncludePrefixes')(), // #backpack-addons babelIncludePrefixes - use: [ - { - loader: require.resolve('babel-loader'), - options: { - customize: require.resolve( - 'babel-preset-react-app/webpack-overrides' - ), - presets: [ - [ - require.resolve('babel-preset-react-app'), - { - runtime: hasJsxRuntime ? 'automatic' : 'classic', - }, - ], - ], - // @remove-on-eject-begin - babelrc: false, - configFile: false, - // Make sure we have a unique cache identifier, erring on the - // side of caution. - // We remove this when the user ejects because the default - // is sane and uses Babel options. Instead of options, we use - // the react-scripts and babel-preset-react-app versions. - cacheIdentifier: getCacheIdentifier( - isEnvProduction - ? 'production' - : isEnvDevelopment && 'development', - [ - 'babel-plugin-named-asset-import', - 'babel-preset-react-app', - 'react-dev-utils', - 'react-scripts', - ] - ), - // @remove-on-eject-end - plugins: [ - isEnvDevelopment && - shouldUseReactRefresh && - require.resolve('react-refresh/babel'), - ].filter(Boolean), - // This is a feature of `babel-loader` for webpack (not Babel itself). - // It enables caching results in ./node_modules/.cache/babel-loader/ - // directory for faster rebuilds. - cacheDirectory: true, - // See #6846 for context on why cacheCompression is disabled - cacheCompression: false, - compact: isEnvProduction, - }, - }, - ].filter(Boolean), - }, - // Process any JS outside of the app with Babel. - // Unlike the application JS, we only compile the standard ES features. - { - test: /\.(js|mjs|cjs)$/, - exclude: /@babel(?:\/|\\{1,2})runtime/, - loader: require.resolve('babel-loader'), - options: { - babelrc: false, - configFile: false, - compact: false, - presets: [ - [ - require.resolve('babel-preset-react-app/dependencies'), - { helpers: true }, - ], - ], - cacheDirectory: true, - // See #6846 for context on why cacheCompression is disabled - cacheCompression: false, - // @remove-on-eject-begin - cacheIdentifier: getCacheIdentifier( - isEnvProduction - ? 'production' - : isEnvDevelopment && 'development', - [ - 'babel-plugin-named-asset-import', - 'babel-preset-react-app', - 'react-dev-utils', - 'react-scripts', - ] - ), - // @remove-on-eject-end - // Babel sourcemaps are needed for debugging into node_modules - // code. Without the options below, debuggers like VSCode - // show incorrect code and set breakpoints on the wrong lines. - sourceMaps: shouldUseSourceMap, - inputSourceMap: shouldUseSourceMap, - }, - }, + ...getJSLoaders( + isEnvProduction, + isEnvDevelopment, + shouldUseReactRefresh, + hasJsxRuntime, + shouldUseSourceMap + ), // "postcss" loader applies autoprefixer to our CSS. // "css" loader resolves paths in CSS and adds assets as dependencies. // "style" loader turns CSS into JS modules that inject