diff --git a/config/webpack.config.js b/config/webpack.config.js index 437a3723..f14e58d7 100644 --- a/config/webpack.config.js +++ b/config/webpack.config.js @@ -1,51 +1,51 @@ -'use strict'; +"use strict"; -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'); -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 { WebpackManifestPlugin } = require('webpack-manifest-plugin'); -const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin'); -const WorkboxWebpackPlugin = require('workbox-webpack-plugin'); -const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin'); -const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent'); -const ESLintPlugin = require('eslint-webpack-plugin'); -const paths = require('./paths'); -const modules = require('./modules'); -const getClientEnvironment = require('./env'); -const ModuleNotFoundPlugin = require('react-dev-utils/ModuleNotFoundPlugin'); -const ForkTsCheckerWebpackPlugin = require('react-dev-utils/ForkTsCheckerWebpackPlugin'); -const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin'); -const postcssNormalize = require('postcss-normalize'); +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"); +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 { WebpackManifestPlugin } = require("webpack-manifest-plugin"); +const InterpolateHtmlPlugin = require("react-dev-utils/InterpolateHtmlPlugin"); +const WorkboxWebpackPlugin = require("workbox-webpack-plugin"); +const ModuleScopePlugin = require("react-dev-utils/ModuleScopePlugin"); +const getCSSModuleLocalIdent = require("react-dev-utils/getCSSModuleLocalIdent"); +const ESLintPlugin = require("eslint-webpack-plugin"); +const paths = require("./paths"); +const modules = require("./modules"); +const getClientEnvironment = require("./env"); +const ModuleNotFoundPlugin = require("react-dev-utils/ModuleNotFoundPlugin"); +const ForkTsCheckerWebpackPlugin = require("react-dev-utils/ForkTsCheckerWebpackPlugin"); +const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin"); +const postcssNormalize = require("postcss-normalize"); const appPackageJson = require(paths.appPackageJson); // Source maps are resource heavy and can cause out of memory issue for large source files. -const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false'; +const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== "false"; const webpackDevClientEntry = require.resolve( - 'react-dev-utils/webpackHotDevClient' + "react-dev-utils/webpackHotDevClient" ); const reactRefreshOverlayEntry = require.resolve( - 'react-dev-utils/refreshOverlayInterop' + "react-dev-utils/refreshOverlayInterop" ); // Some apps do not need the benefits of saving a web request, so not inlining the chunk // makes for a smoother build process. -const shouldInlineRuntimeChunk = process.env.INLINE_RUNTIME_CHUNK !== 'false'; +const shouldInlineRuntimeChunk = process.env.INLINE_RUNTIME_CHUNK !== "false"; -const emitErrorsAsWarnings = process.env.ESLINT_NO_DEV_ERRORS === 'true'; -const disableESLintPlugin = process.env.DISABLE_ESLINT_PLUGIN === 'true'; +const emitErrorsAsWarnings = process.env.ESLINT_NO_DEV_ERRORS === "true"; +const disableESLintPlugin = process.env.DISABLE_ESLINT_PLUGIN === "true"; const imageInlineSizeLimit = parseInt( - process.env.IMAGE_INLINE_SIZE_LIMIT || '10000' + process.env.IMAGE_INLINE_SIZE_LIMIT || "10000" ); // Check if TypeScript is setup @@ -61,12 +61,12 @@ const sassRegex = /\.(scss|sass)$/; const sassModuleRegex = /\.module\.(scss|sass)$/; const hasJsxRuntime = (() => { - if (process.env.DISABLE_NEW_JSX_TRANSFORM === 'true') { + if (process.env.DISABLE_NEW_JSX_TRANSFORM === "true") { return false; } try { - require.resolve('react/jsx-runtime'); + require.resolve("react/jsx-runtime"); return true; } catch (e) { return false; @@ -76,14 +76,13 @@ const hasJsxRuntime = (() => { // This is the production and development configuration. // It is focused on developer experience, fast rebuilds, and a minimal bundle. module.exports = function (webpackEnv) { - - const isEnvDevelopment = webpackEnv === 'development'; - const isEnvProduction = webpackEnv === 'production'; + const isEnvDevelopment = webpackEnv === "development"; + const isEnvProduction = webpackEnv === "production"; // Variable used for enabling profiling in Production // passed into alias object. Uses a flag if passed into the build command const isEnvProductionProfile = - isEnvProduction && process.argv.includes('--profile'); + isEnvProduction && process.argv.includes("--profile"); // We will provide `paths.publicUrlOrPath` to our app // as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript. @@ -96,61 +95,60 @@ module.exports = function (webpackEnv) { // common function to get style loaders const getStyleLoaders = (cssOptions, preProcessor) => { const loaders = [ - isEnvDevelopment && require.resolve('style-loader'), + isEnvDevelopment && require.resolve("style-loader"), isEnvProduction && { loader: MiniCssExtractPlugin.loader, // css is located in `static/css`, use '../../' to locate index.html folder // in production `paths.publicUrlOrPath` can be a relative path - options: paths.publicUrlOrPath.startsWith('.') - ? { publicPath: '../../' } - : {}, + options: paths.publicUrlOrPath.startsWith(".") + ? { publicPath: "../../" } + : {} }, { - loader: require.resolve('css-loader'), - options: cssOptions, + loader: require.resolve("css-loader"), + options: cssOptions }, { // Options for PostCSS as we reference these options twice // Adds vendor prefixing based on your specified browser support in // package.json - loader: require.resolve('postcss-loader'), + loader: require.resolve("postcss-loader"), options: { //ident: 'postcss', postcssOptions: { plugins: [ - require('postcss-flexbugs-fixes'), - require('postcss-preset-env')({ + require("postcss-flexbugs-fixes"), + require("postcss-preset-env")({ autoprefixer: { - flexbox: 'no-2009', + flexbox: "no-2009" }, - stage: 3, + 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(), + postcssNormalize() ] - } + } // Necessary for external CSS imports to work // https://github.com/facebook/create-react-app/issues/2677 - - }, - }, + } + } ].filter(Boolean); if (preProcessor) { loaders.push( { - loader: require.resolve('resolve-url-loader'), + loader: require.resolve("resolve-url-loader"), options: { sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment, - root: paths.appSrc, - }, + root: paths.appSrc + } }, { loader: require.resolve(preProcessor), options: { - sourceMap: true, - }, + sourceMap: true + } } ); } @@ -158,20 +156,19 @@ module.exports = function (webpackEnv) { }; return { - mode: isEnvProduction ? 'production' : isEnvDevelopment && 'development', + mode: isEnvProduction ? "production" : isEnvDevelopment && "development", // Stop compilation early in production bail: isEnvProduction, devtool: isEnvProduction - ? shouldUseSourceMap - ? 'source-map' - : false - : isEnvDevelopment && 'cheap-module-source-map', + ? shouldUseSourceMap + ? "source-map" + : false + : isEnvDevelopment && "cheap-module-source-map", // These are the "entry points" to our application. // This means they will be the "root" imports that are included in JS bundle. - entry: + entry: isEnvDevelopment && !shouldUseReactRefresh ? [ - // Include an alternative client for WebpackDevServer. A client's job is to // connect to WebpackDevServer by a socket and get notified about changes. // When you save a file, the client will either apply hot updates (in case @@ -188,12 +185,12 @@ module.exports = function (webpackEnv) { // the webpack plugin takes care of injecting the dev client for us. webpackDevClientEntry, // Finally, this is your app's code: - paths.appIndexJs, + paths.appIndexJs // We include the app code last so that if there is a runtime error during // initialization, it doesn't blow up the WebpackDevServer client, and // changing JS code would still trigger a refresh. ] - : paths.appIndexJs, + : paths.appIndexJs, output: { // The build folder. path: isEnvProduction ? paths.appBuild : undefined, @@ -202,31 +199,32 @@ module.exports = function (webpackEnv) { // There will be one main bundle, and one file per asynchronous chunk. // In development, it does not produce real files. filename: isEnvProduction - ? 'static/js/[name].[contenthash:8].js' - : isEnvDevelopment && 'static/js/[name].js', + ? "static/js/[name].[contenthash:8].js" + : isEnvDevelopment && "static/js/[name].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' - : isEnvDevelopment && 'static/js/[name].chunk.js', + ? "static/js/[name].[contenthash:8].chunk.js" + : isEnvDevelopment && "static/js/[name].chunk.js", // webpack uses `publicPath` to determine where the app is being served from. // It requires a trailing slash, or the file assets will get an incorrect path. // We inferred the "public path" (such as / or /my-project) from homepage. publicPath: paths.publicUrlOrPath, // Point sourcemap entries to original disk location (format as URL on Windows) devtoolModuleFilenameTemplate: isEnvProduction - ? info => + ? (info) => path .relative(paths.appSrc, info.absoluteResourcePath) - .replace(/\\/g, '/') + .replace(/\\/g, "/") : isEnvDevelopment && - (info => path.resolve(info.absoluteResourcePath).replace(/\\/g, '/')), + ((info) => + path.resolve(info.absoluteResourcePath).replace(/\\/g, "/")) // Prevents conflicts when multiple webpack runtimes (from different apps) // are used on the same page. // this defaults to 'window', but by setting it to 'this' then - // module chunks which are built will work in web workers as well. - //chunkLoadingGlobal: `webpackJsonp${appPackageJson.name}` + // module chunks which are built will work in web workers as well. + //chunkLoadingGlobal: `webpackJsonp${appPackageJson.name}` }, optimization: { minimize: isEnvProduction, @@ -240,7 +238,7 @@ module.exports = function (webpackEnv) { // into invalid ecma 5 code. This is why the 'compress' and 'output' // sections only apply transformations that are ecma 5 safe // https://github.com/facebook/create-react-app/pull/4234 - ecma: 8, + ecma: 8 }, compress: { ecma: 5, @@ -254,10 +252,10 @@ module.exports = function (webpackEnv) { // https://github.com/facebook/create-react-app/issues/5250 // Pending further investigation: // https://github.com/terser-js/terser/issues/120 - inline: 2, + inline: 2 }, mangle: { - safari10: true, + safari10: true }, // Added for profiling in devtools keep_classnames: isEnvProductionProfile, @@ -267,9 +265,9 @@ module.exports = function (webpackEnv) { comments: false, // Turned on because emoji and regex is not minified properly using default // https://github.com/facebook/create-react-app/issues/2488 - ascii_only: true, - }, - }, + ascii_only: true + } + } //sourceMap: shouldUseSourceMap, }), // This is only used in production mode @@ -283,40 +281,42 @@ module.exports = function (webpackEnv) { inline: false, // `annotation: true` appends the sourceMappingURL to the end of // the css file, helping the browser find the sourcemap - annotation: true, + annotation: true } - : false, + : false }, cssProcessorPluginOptions: { - preset: ['default', { minifyFontValues: { removeQuotes: false } }], - }, - }), + preset: ["default", { minifyFontValues: { removeQuotes: false } }] + } + }) ], // 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, + //chunks: 'all', + //name: isEnvDevelopment, //}, splitChunks: false, // 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}`, - }, + name: (entrypoint) => `runtime-${entrypoint.name}` + } }, resolve: { fallback: { fs: false, - stream: false, + stream: false, + url: require.resolve("url/"), + browser: false }, // This allows you to set a fallback for where webpack should look for modules. // We placed these paths second because we want `node_modules` to "win" // if there are any conflicts. This matches Node resolution mechanism. // https://github.com/facebook/create-react-app/issues/253 - modules: ['node_modules', paths.appNodeModules].concat( + modules: ["node_modules", paths.appNodeModules].concat( modules.additionalModulePaths || [] ), // These are the reasonable defaults supported by the Node ecosystem. @@ -326,18 +326,18 @@ module.exports = function (webpackEnv) { // `web` extension prefixes have been added for better support // for React Native Web. extensions: paths.moduleFileExtensions - .map(ext => `.${ext}`) - .filter(ext => useTypeScript || !ext.includes('ts')), + .map((ext) => `.${ext}`) + .filter((ext) => useTypeScript || !ext.includes("ts")), alias: { // Support React Native Web // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/ - 'react-native': 'react-native-web', + "react-native": "react-native-web", // Allows for better profiling with ReactDevTools ...(isEnvProductionProfile && { - 'react-dom$': 'react-dom/profiling', - 'scheduler/tracing': 'scheduler/tracing-profiling', + "react-dom$": "react-dom/profiling", + "scheduler/tracing": "scheduler/tracing-profiling" }), - ...(modules.webpackAliases || {}), + ...(modules.webpackAliases || {}) }, plugins: [ // Adds support for installing with Plug'n'Play, leading to faster installs and adding @@ -350,16 +350,16 @@ 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, - reactRefreshOverlayEntry, - ]), - ], + reactRefreshOverlayEntry + ]) + ] }, 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), - ], + PnpWebpackPlugin.moduleLoader(module) + ] }, module: { strictExportPresence: true, @@ -375,53 +375,57 @@ module.exports = function (webpackEnv) { // https://github.com/jshttp/mime-db { test: [/\.avif$/], - loader: require.resolve('url-loader'), + loader: require.resolve("url-loader"), options: { limit: imageInlineSizeLimit, - mimetype: 'image/avif', - name: 'static/media/[name].[hash:8].[ext]', - }, + mimetype: "image/avif", + name: "static/media/[name].[hash:8].[ext]" + } }, // "url" loader works like "file" loader except that it embeds assets // smaller than specified limit in bytes as data URLs to avoid requests. // A missing `test` is equivalent to a match. { test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/], - loader: require.resolve('url-loader'), + loader: require.resolve("url-loader"), options: { limit: imageInlineSizeLimit, - name: 'static/media/[name].[hash:8].[ext]', - }, + name: "static/media/[name].[hash:8].[ext]" + } }, // Process application JS with Babel. // The preset includes JSX, Flow, TypeScript, and some ESnext features. { test: /\.(js|mjs|jsx|ts|tsx)$/, include: paths.appSrc, - loader: require.resolve('babel-loader'), + loader: require.resolve("babel-loader"), options: { - // customize: require.resolve( - // '@babel/preset-react/webpack-overrides' - // ), + // customize: require.resolve( + // '@babel/preset-react/webpack-overrides' + // ), presets: [ "@babel/preset-env", - ["@babel/preset-react", { runtime: hasJsxRuntime ? "automatic" : "classic" }]], - + [ + "@babel/preset-react", + { runtime: hasJsxRuntime ? "automatic" : "classic" } + ] + ], + plugins: [ [ - require.resolve('babel-plugin-named-asset-import'), + require.resolve("babel-plugin-named-asset-import"), { loaderMap: { svg: { ReactComponent: - '@svgr/webpack?-svgo,+titleProp,+ref![path]', - }, - }, - }, + "@svgr/webpack?-svgo,+titleProp,+ref![path]" + } + } + } ], isEnvDevelopment && shouldUseReactRefresh && - require.resolve('react-refresh/babel'), + 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/ @@ -429,32 +433,33 @@ module.exports = function (webpackEnv) { cacheDirectory: true, // See #6846 for context on why cacheCompression is disabled cacheCompression: false, - compact: isEnvProduction, - }, - }, + compact: isEnvProduction + } + }, // Process any JS outside of the app with Babel. // Unlike the application JS, we only compile the standard ES features. { test: /\.(js|mjs)$/, //exclude: /@babel(?:\/|\\{1,2})runtime/, - loader: require.resolve('babel-loader'), + loader: require.resolve("babel-loader"), options: { babelrc: false, configFile: false, compact: false, presets: [ "@babel/preset-env", - ["@babel/preset-react", { helpers: true }]], + ["@babel/preset-react", { helpers: true }] + ], cacheDirectory: true, // See #6846 for context on why cacheCompression is disabled cacheCompression: false, - + // 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, - }, + inputSourceMap: shouldUseSourceMap + } }, // "postcss" loader applies autoprefixer to our CSS. // "css" loader resolves paths in CSS and adds assets as dependencies. @@ -470,13 +475,13 @@ module.exports = function (webpackEnv) { importLoaders: 1, sourceMap: isEnvProduction ? shouldUseSourceMap - : isEnvDevelopment, + : isEnvDevelopment }), // Don't consider CSS imports dead code even if the // containing package claims to have no side effects. // Remove this when webpack adds a warning or an error for this. // See https://github.com/webpack/webpack/issues/6571 - sideEffects: true, + sideEffects: true }, // Adds support for CSS Modules (https://github.com/css-modules/css-modules) // using the extension .module.css @@ -488,9 +493,9 @@ module.exports = function (webpackEnv) { ? shouldUseSourceMap : isEnvDevelopment, modules: { - getLocalIdent: getCSSModuleLocalIdent, - }, - }), + getLocalIdent: getCSSModuleLocalIdent + } + }) }, // Opt-in support for SASS (using .scss or .sass extensions). // By default we support SASS Modules with the @@ -503,15 +508,15 @@ module.exports = function (webpackEnv) { importLoaders: 3, sourceMap: isEnvProduction ? shouldUseSourceMap - : isEnvDevelopment, + : isEnvDevelopment }, - 'sass-loader' + "sass-loader" ), // Don't consider CSS imports dead code even if the // containing package claims to have no side effects. // Remove this when webpack adds a warning or an error for this. // See https://github.com/webpack/webpack/issues/6571 - sideEffects: true, + sideEffects: true }, // Adds support for CSS Modules, but using SASS // using the extension .module.scss or .module.sass @@ -524,11 +529,11 @@ module.exports = function (webpackEnv) { ? shouldUseSourceMap : isEnvDevelopment, modules: { - getLocalIdent: getCSSModuleLocalIdent, - }, + getLocalIdent: getCSSModuleLocalIdent + } }, - 'sass-loader' - ), + "sass-loader" + ) }, // "file" loader makes sure those assets get served by WebpackDevServer. // When you `import` an asset, you get its (virtual) filename. @@ -536,21 +541,21 @@ 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'), + 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]', - }, - }, + name: "static/media/[name].[hash:8].[ext]" + } + } // ** STOP ** Are you adding a new loader? // Make sure to add the new loader(s) before the "file" loader. - ], - }, - ], + ] + } + ] }, plugins: [ // Generates an `index.html` file with the