diff --git a/config/env.js b/config/env.js
index fae806a74..ffa7e496a 100644
--- a/config/env.js
+++ b/config/env.js
@@ -1,13 +1,17 @@
-const fs = require("fs")
-const path = require("path")
-const paths = require("./paths")
+'use strict';
+
+const fs = require('fs');
+const path = require('path');
+const paths = require('./paths');
// Make sure that including paths.js after env.js will read .env variables.
-delete require.cache[require.resolve("./paths")]
+delete require.cache[require.resolve('./paths')];
-const NODE_ENV = process.env.NODE_ENV
+const NODE_ENV = process.env.NODE_ENV;
if (!NODE_ENV) {
- throw new Error("The NODE_ENV environment variable is required but was not specified.")
+ throw new Error(
+ 'The NODE_ENV environment variable is required but was not specified.'
+ );
}
// https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use
@@ -16,25 +20,25 @@ const dotenvFiles = [
// Don't include `.env.local` for `test` environment
// since normally you expect tests to produce the same
// results for everyone
- NODE_ENV !== "test" && `${paths.dotenv}.local`,
+ NODE_ENV !== 'test' && `${paths.dotenv}.local`,
`${paths.dotenv}.${NODE_ENV}`,
paths.dotenv,
-].filter(Boolean)
+].filter(Boolean);
// Load environment variables from .env* files. Suppress warnings using silent
// if this file is missing. dotenv will never modify any environment variables
// that have already been set. Variable expansion is supported in .env files.
// https://github.com/motdotla/dotenv
// https://github.com/motdotla/dotenv-expand
-dotenvFiles.forEach((dotenvFile) => {
+dotenvFiles.forEach(dotenvFile => {
if (fs.existsSync(dotenvFile)) {
- require("dotenv-expand")(
- require("dotenv").config({
+ require('dotenv-expand')(
+ require('dotenv').config({
path: dotenvFile,
})
- )
+ );
}
-})
+});
// We support resolving modules according to `NODE_PATH`.
// This lets you use absolute paths in imports inside large monorepos:
@@ -45,29 +49,29 @@ dotenvFiles.forEach((dotenvFile) => {
// Otherwise, we risk importing Node.js core modules into an app instead of webpack shims.
// https://github.com/facebook/create-react-app/issues/1023#issuecomment-265344421
// We also resolve them to make sure all tools using them work consistently.
-const appDirectory = fs.realpathSync(process.cwd())
-process.env.NODE_PATH = (process.env.NODE_PATH || "")
+const appDirectory = fs.realpathSync(process.cwd());
+process.env.NODE_PATH = (process.env.NODE_PATH || '')
.split(path.delimiter)
- .filter((folder) => folder && !path.isAbsolute(folder))
- .map((folder) => path.resolve(appDirectory, folder))
- .join(path.delimiter)
+ .filter(folder => folder && !path.isAbsolute(folder))
+ .map(folder => path.resolve(appDirectory, folder))
+ .join(path.delimiter);
// Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be
// injected into the application via DefinePlugin in webpack configuration.
-const REACT_APP = /^REACT_APP_/i
+const REACT_APP = /^REACT_APP_/i;
function getClientEnvironment(publicUrl) {
const raw = Object.keys(process.env)
- .filter((key) => REACT_APP.test(key))
+ .filter(key => REACT_APP.test(key))
.reduce(
(env, key) => {
- env[key] = process.env[key]
- return env
+ env[key] = process.env[key];
+ return env;
},
{
// Useful for determining whether we’re running in production mode.
// Most importantly, it switches React into the correct mode.
- NODE_ENV: process.env.NODE_ENV || "development",
+ NODE_ENV: process.env.NODE_ENV || 'development',
// Useful for resolving the correct path to static assets in `public`.
// For example, .
// This should only be used as an escape hatch. Normally you would put
@@ -82,21 +86,19 @@ function getClientEnvironment(publicUrl) {
WDS_SOCKET_PATH: process.env.WDS_SOCKET_PATH,
WDS_SOCKET_PORT: process.env.WDS_SOCKET_PORT,
// Whether or not react-refresh is enabled.
- // react-refresh is not 100% stable at this time,
- // which is why it's disabled by default.
// It is defined here so it is available in the webpackHotDevClient.
- FAST_REFRESH: process.env.FAST_REFRESH !== "false",
+ FAST_REFRESH: process.env.FAST_REFRESH !== 'false',
}
- )
+ );
// Stringify all values so we can feed into webpack DefinePlugin
const stringified = {
- "process.env": Object.keys(raw).reduce((env, key) => {
- env[key] = JSON.stringify(raw[key])
- return env
+ 'process.env': Object.keys(raw).reduce((env, key) => {
+ env[key] = JSON.stringify(raw[key]);
+ return env;
}, {}),
- }
+ };
- return { raw, stringified }
+ return { raw, stringified };
}
-module.exports = getClientEnvironment
+module.exports = getClientEnvironment;
diff --git a/config/getHttpsConfig.js b/config/getHttpsConfig.js
index 7efa29a82..013d493c1 100644
--- a/config/getHttpsConfig.js
+++ b/config/getHttpsConfig.js
@@ -1,25 +1,33 @@
-const fs = require("fs")
-const path = require("path")
-const crypto = require("crypto")
-const chalk = require("react-dev-utils/chalk")
-const paths = require("./paths")
+'use strict';
+
+const fs = require('fs');
+const path = require('path');
+const crypto = require('crypto');
+const chalk = require('react-dev-utils/chalk');
+const paths = require('./paths');
// Ensure the certificate and key provided are valid and if not
// throw an easy to debug error
function validateKeyAndCerts({ cert, key, keyFile, crtFile }) {
- let encrypted
+ let encrypted;
try {
// publicEncrypt will throw an error with an invalid cert
- encrypted = crypto.publicEncrypt(cert, Buffer.from("test"))
+ encrypted = crypto.publicEncrypt(cert, Buffer.from('test'));
} catch (err) {
- throw new Error(`The certificate "${chalk.yellow(crtFile)}" is invalid.\n${err.message}`)
+ throw new Error(
+ `The certificate "${chalk.yellow(crtFile)}" is invalid.\n${err.message}`
+ );
}
try {
// privateDecrypt will throw an error with an invalid key
- crypto.privateDecrypt(key, encrypted)
+ crypto.privateDecrypt(key, encrypted);
} catch (err) {
- throw new Error(`The certificate key "${chalk.yellow(keyFile)}" is invalid.\n${err.message}`)
+ throw new Error(
+ `The certificate key "${chalk.yellow(keyFile)}" is invalid.\n${
+ err.message
+ }`
+ );
}
}
@@ -27,30 +35,32 @@ function validateKeyAndCerts({ cert, key, keyFile, crtFile }) {
function readEnvFile(file, type) {
if (!fs.existsSync(file)) {
throw new Error(
- `You specified ${chalk.cyan(type)} in your env, but the file "${chalk.yellow(file)}" can't be found.`
- )
+ `You specified ${chalk.cyan(
+ type
+ )} in your env, but the file "${chalk.yellow(file)}" can't be found.`
+ );
}
- return fs.readFileSync(file)
+ return fs.readFileSync(file);
}
// Get the https config
// Return cert files if provided in env, otherwise just true or false
function getHttpsConfig() {
- const { SSL_CRT_FILE, SSL_KEY_FILE, HTTPS } = process.env
- const isHttps = HTTPS === "true"
+ const { SSL_CRT_FILE, SSL_KEY_FILE, HTTPS } = process.env;
+ const isHttps = HTTPS === 'true';
if (isHttps && SSL_CRT_FILE && SSL_KEY_FILE) {
- const crtFile = path.resolve(paths.appPath, SSL_CRT_FILE)
- const keyFile = path.resolve(paths.appPath, SSL_KEY_FILE)
+ const crtFile = path.resolve(paths.appPath, SSL_CRT_FILE);
+ const keyFile = path.resolve(paths.appPath, SSL_KEY_FILE);
const config = {
- cert: readEnvFile(crtFile, "SSL_CRT_FILE"),
- key: readEnvFile(keyFile, "SSL_KEY_FILE"),
- }
+ cert: readEnvFile(crtFile, 'SSL_CRT_FILE'),
+ key: readEnvFile(keyFile, 'SSL_KEY_FILE'),
+ };
- validateKeyAndCerts({ ...config, keyFile, crtFile })
- return config
+ validateKeyAndCerts({ ...config, keyFile, crtFile });
+ return config;
}
- return isHttps
+ return isHttps;
}
-module.exports = getHttpsConfig
+module.exports = getHttpsConfig;
diff --git a/config/jest/babelTransform.js b/config/jest/babelTransform.js
index 9bf17b074..5b391e405 100644
--- a/config/jest/babelTransform.js
+++ b/config/jest/babelTransform.js
@@ -1,27 +1,29 @@
-const babelJest = require("babel-jest")
+'use strict';
+
+const babelJest = require('babel-jest').default;
const hasJsxRuntime = (() => {
- if (process.env.DISABLE_NEW_JSX_TRANSFORM === "true") {
- return false
+ if (process.env.DISABLE_NEW_JSX_TRANSFORM === 'true') {
+ return false;
}
try {
- require.resolve("react/jsx-runtime")
- return true
+ require.resolve('react/jsx-runtime');
+ return true;
} catch (e) {
- return false
+ return false;
}
-})()
+})();
module.exports = babelJest.createTransformer({
presets: [
[
- require.resolve("babel-preset-react-app"),
+ require.resolve('babel-preset-react-app'),
{
- runtime: hasJsxRuntime ? "automatic" : "classic",
+ runtime: hasJsxRuntime ? 'automatic' : 'classic',
},
],
],
babelrc: false,
configFile: false,
-})
+});
diff --git a/config/jest/cssTransform.js b/config/jest/cssTransform.js
index a97276c8d..8f6511481 100644
--- a/config/jest/cssTransform.js
+++ b/config/jest/cssTransform.js
@@ -1,12 +1,14 @@
+'use strict';
+
// This is a custom Jest transformer turning style imports into empty objects.
// http://facebook.github.io/jest/docs/en/webpack.html
module.exports = {
process() {
- return "module.exports = {};"
+ return 'module.exports = {};';
},
getCacheKey() {
// The output is always the same.
- return "cssTransform"
+ return 'cssTransform';
},
-}
+};
diff --git a/config/jest/fileTransform.js b/config/jest/fileTransform.js
index d72065560..aab67618c 100644
--- a/config/jest/fileTransform.js
+++ b/config/jest/fileTransform.js
@@ -1,20 +1,22 @@
-const path = require("path")
-const camelcase = require("camelcase")
+'use strict';
+
+const path = require('path');
+const camelcase = require('camelcase');
// This is a custom Jest transformer turning file imports into filenames.
// http://facebook.github.io/jest/docs/en/webpack.html
module.exports = {
process(src, filename) {
- const assetFilename = JSON.stringify(path.basename(filename))
+ const assetFilename = JSON.stringify(path.basename(filename));
if (filename.match(/\.svg$/)) {
// Based on how SVGR generates a component name:
// https://github.com/smooth-code/svgr/blob/01b194cf967347d43d4cbe6b434404731b87cf27/packages/core/src/state.js#L6
const pascalCaseFilename = camelcase(path.parse(filename).name, {
pascalCase: true,
- })
- const componentName = `Svg${pascalCaseFilename}`
+ });
+ const componentName = `Svg${pascalCaseFilename}`;
return `const React = require('react');
module.exports = {
__esModule: true,
@@ -30,9 +32,9 @@ module.exports = {
})
};
}),
- };`
+ };`;
}
- return `module.exports = ${assetFilename};`
+ return `module.exports = ${assetFilename};`;
},
-}
+};
diff --git a/config/modules.js b/config/modules.js
index 6fcf390c2..d63e41d78 100644
--- a/config/modules.js
+++ b/config/modules.js
@@ -1,8 +1,10 @@
-const fs = require("fs")
-const path = require("path")
-const paths = require("./paths")
-const chalk = require("react-dev-utils/chalk")
-const resolve = require("resolve")
+'use strict';
+
+const fs = require('fs');
+const path = require('path');
+const paths = require('./paths');
+const chalk = require('react-dev-utils/chalk');
+const resolve = require('resolve');
/**
* Get additional module paths based on the baseUrl of a compilerOptions object.
@@ -10,23 +12,23 @@ const resolve = require("resolve")
* @param {Object} options
*/
function getAdditionalModulePaths(options = {}) {
- const baseUrl = options.baseUrl
+ const baseUrl = options.baseUrl;
if (!baseUrl) {
- return ""
+ return '';
}
- const baseUrlResolved = path.resolve(paths.appPath, baseUrl)
+ const baseUrlResolved = path.resolve(paths.appPath, baseUrl);
// We don't need to do anything if `baseUrl` is set to `node_modules`. This is
// the default behavior.
- if (path.relative(paths.appNodeModules, baseUrlResolved) === "") {
- return null
+ if (path.relative(paths.appNodeModules, baseUrlResolved) === '') {
+ return null;
}
// Allow the user set the `baseUrl` to `appSrc`.
- if (path.relative(paths.appSrc, baseUrlResolved) === "") {
- return [paths.appSrc]
+ if (path.relative(paths.appSrc, baseUrlResolved) === '') {
+ return [paths.appSrc];
}
// If the path is equal to the root directory we ignore it here.
@@ -34,17 +36,17 @@ function getAdditionalModulePaths(options = {}) {
// not transpiled outside of `src`. We do allow importing them with the
// absolute path (e.g. `src/Components/Button.js`) but we set that up with
// an alias.
- if (path.relative(paths.appPath, baseUrlResolved) === "") {
- return null
+ if (path.relative(paths.appPath, baseUrlResolved) === '') {
+ return null;
}
// Otherwise, throw an error.
throw new Error(
chalk.red.bold(
"Your project's `baseUrl` can only be set to `src` or `node_modules`." +
- " Create React App does not support other values at this time."
+ ' Create React App does not support other values at this time.'
)
- )
+ );
}
/**
@@ -53,18 +55,18 @@ function getAdditionalModulePaths(options = {}) {
* @param {*} options
*/
function getWebpackAliases(options = {}) {
- const baseUrl = options.baseUrl
+ const baseUrl = options.baseUrl;
if (!baseUrl) {
- return {}
+ return {};
}
- const baseUrlResolved = path.resolve(paths.appPath, baseUrl)
+ const baseUrlResolved = path.resolve(paths.appPath, baseUrl);
- if (path.relative(paths.appPath, baseUrlResolved) === "") {
+ if (path.relative(paths.appPath, baseUrlResolved) === '') {
return {
src: paths.appSrc,
- }
+ };
}
}
@@ -74,59 +76,59 @@ function getWebpackAliases(options = {}) {
* @param {*} options
*/
function getJestAliases(options = {}) {
- const baseUrl = options.baseUrl
+ const baseUrl = options.baseUrl;
if (!baseUrl) {
- return {}
+ return {};
}
- const baseUrlResolved = path.resolve(paths.appPath, baseUrl)
+ const baseUrlResolved = path.resolve(paths.appPath, baseUrl);
- if (path.relative(paths.appPath, baseUrlResolved) === "") {
+ if (path.relative(paths.appPath, baseUrlResolved) === '') {
return {
- "^src/(.*)$": "/src/$1",
- }
+ '^src/(.*)$': '/src/$1',
+ };
}
}
function getModules() {
// Check if TypeScript is setup
- const hasTsConfig = fs.existsSync(paths.appTsConfig)
- const hasJsConfig = fs.existsSync(paths.appJsConfig)
+ const hasTsConfig = fs.existsSync(paths.appTsConfig);
+ const hasJsConfig = fs.existsSync(paths.appJsConfig);
if (hasTsConfig && hasJsConfig) {
throw new Error(
- "You have both a tsconfig.json and a jsconfig.json. If you are using TypeScript please remove your jsconfig.json file."
- )
+ 'You have both a tsconfig.json and a jsconfig.json. If you are using TypeScript please remove your jsconfig.json file.'
+ );
}
- let config
+ let config;
// If there's a tsconfig.json we assume it's a
// TypeScript project and set up the config
// based on tsconfig.json
if (hasTsConfig) {
- const ts = require(resolve.sync("typescript", {
+ const ts = require(resolve.sync('typescript', {
basedir: paths.appNodeModules,
- }))
- config = ts.readConfigFile(paths.appTsConfig, ts.sys.readFile).config
+ }));
+ config = ts.readConfigFile(paths.appTsConfig, ts.sys.readFile).config;
// Otherwise we'll check if there is jsconfig.json
// for non TS projects.
} else if (hasJsConfig) {
- config = require(paths.appJsConfig)
+ config = require(paths.appJsConfig);
}
- config = config || {}
- const options = config.compilerOptions || {}
+ config = config || {};
+ const options = config.compilerOptions || {};
- const additionalModulePaths = getAdditionalModulePaths(options)
+ const additionalModulePaths = getAdditionalModulePaths(options);
return {
additionalModulePaths: additionalModulePaths,
webpackAliases: getWebpackAliases(options),
jestAliases: getJestAliases(options),
hasTsConfig,
- }
+ };
}
-module.exports = getModules()
+module.exports = getModules();
diff --git a/config/paths.js b/config/paths.js
index f73f7846e..f0a6cd9c9 100644
--- a/config/paths.js
+++ b/config/paths.js
@@ -1,11 +1,13 @@
-const path = require("path")
-const fs = require("fs")
-const getPublicUrlOrPath = require("react-dev-utils/getPublicUrlOrPath")
+'use strict';
+
+const path = require('path');
+const fs = require('fs');
+const getPublicUrlOrPath = require('react-dev-utils/getPublicUrlOrPath');
// Make sure any symlinks in the project folder are resolved:
// https://github.com/facebook/create-react-app/issues/637
-const appDirectory = fs.realpathSync(process.cwd())
-const resolveApp = (relativePath) => path.resolve(appDirectory, relativePath)
+const appDirectory = fs.realpathSync(process.cwd());
+const resolveApp = relativePath => path.resolve(appDirectory, relativePath);
// We use `PUBLIC_URL` environment variable or "homepage" field to infer
// "public path" at which the app is served.
@@ -14,56 +16,62 @@ const resolveApp = (relativePath) => path.resolve(appDirectory, relativePath)
// We can't use a relative path in HTML because we don't want to load something
// like /todos/42/static/js/bundle.7289d.js. We have to know the root.
const publicUrlOrPath = getPublicUrlOrPath(
- process.env.NODE_ENV === "development",
- require(resolveApp("package.json")).homepage,
+ process.env.NODE_ENV === 'development',
+ require(resolveApp('package.json')).homepage,
process.env.PUBLIC_URL
-)
+);
-const buildPath = process.env.BUILD_PATH || "build"
+const buildPath = process.env.BUILD_PATH || 'build';
const moduleFileExtensions = [
- "web.mjs",
- "mjs",
- "web.js",
- "js",
- "web.ts",
- "ts",
- "web.tsx",
- "tsx",
- "json",
- "web.jsx",
- "jsx",
-]
+ 'web.mjs',
+ 'mjs',
+ 'web.js',
+ 'js',
+ 'web.ts',
+ 'ts',
+ 'web.tsx',
+ 'tsx',
+ 'json',
+ 'web.jsx',
+ 'jsx',
+];
// Resolve file paths in the same order as webpack
const resolveModule = (resolveFn, filePath) => {
- const extension = moduleFileExtensions.find((extension) => fs.existsSync(resolveFn(`${filePath}.${extension}`)))
+ const extension = moduleFileExtensions.find(extension =>
+ fs.existsSync(resolveFn(`${filePath}.${extension}`))
+ );
if (extension) {
- return resolveFn(`${filePath}.${extension}`)
+ return resolveFn(`${filePath}.${extension}`);
}
- return resolveFn(`${filePath}.js`)
-}
+ return resolveFn(`${filePath}.js`);
+};
// config after eject: we're in ./config/
module.exports = {
- dotenv: resolveApp(".env"),
- appPath: resolveApp("."),
+ dotenv: resolveApp('.env'),
+ appPath: resolveApp('.'),
appBuild: resolveApp(buildPath),
- appPublic: resolveApp("public"),
- appHtml: resolveApp("public/index.html"),
- appIndexJs: resolveModule(resolveApp, "src/index"),
- appPackageJson: resolveApp("package.json"),
- appSrc: resolveApp("src"),
- appTsConfig: resolveApp("tsconfig.json"),
- appJsConfig: resolveApp("jsconfig.json"),
- yarnLockFile: resolveApp("yarn.lock"),
- testsSetup: resolveModule(resolveApp, "src/setupTests"),
- proxySetup: resolveApp("src/setupProxy.js"),
- appNodeModules: resolveApp("node_modules"),
- swSrc: resolveModule(resolveApp, "src/service-worker"),
+ appPublic: resolveApp('public'),
+ appHtml: resolveApp('public/index.html'),
+ appIndexJs: resolveModule(resolveApp, 'src/index'),
+ appPackageJson: resolveApp('package.json'),
+ appSrc: resolveApp('src'),
+ appTsConfig: resolveApp('tsconfig.json'),
+ appJsConfig: resolveApp('jsconfig.json'),
+ yarnLockFile: resolveApp('yarn.lock'),
+ testsSetup: resolveModule(resolveApp, 'src/setupTests'),
+ proxySetup: resolveApp('src/setupProxy.js'),
+ appNodeModules: resolveApp('node_modules'),
+ appWebpackCache: resolveApp('node_modules/.cache'),
+ appTsBuildInfoFile: resolveApp('node_modules/.cache/tsconfig.tsbuildinfo'),
+ swSrc: resolveModule(resolveApp, 'src/service-worker'),
publicUrlOrPath,
-}
+};
+
+
-module.exports.moduleFileExtensions = moduleFileExtensions
+module.exports.moduleFileExtensions = moduleFileExtensions;
diff --git a/config/webpack.config.js b/config/webpack.config.js
index 8436e6e33..d0353fd84 100644
--- a/config/webpack.config.js
+++ b/config/webpack.config.js
@@ -1,115 +1,175 @@
-const fs = require("fs")
-const path = require("path")
-const webpack = require("webpack")
-const resolve = require("resolve")
-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 CssMinimizerPlugin = require("css-minimizer-webpack-plugin")
-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 CompressionPlugin = require("compression-webpack-plugin");
+'use strict';
-const appPackageJson = require(paths.appPackageJson)
+const fs = require('fs');
+const path = require('path');
+const webpack = require('webpack');
+const resolve = require('resolve');
+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 CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
+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 =
+ process.env.TSC_COMPILE_ON_ERROR === 'true'
+ ? require('react-dev-utils/ForkTsCheckerWarningWebpackPlugin')
+ : require('react-dev-utils/ForkTsCheckerWebpackPlugin');
+const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
+
+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"
+const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';
-const webpackDevClientEntry = require.resolve("react-dev-utils/webpackHotDevClient")
-const reactRefreshOverlayEntry = require.resolve("react-dev-utils/refreshOverlayInterop")
+const reactRefreshRuntimeEntry = require.resolve('react-refresh/runtime');
+const reactRefreshWebpackPluginRuntimeEntry = require.resolve(
+ '@pmmmwh/react-refresh-webpack-plugin'
+);
+const babelRuntimeEntry = require.resolve('babel-preset-react-app');
+const babelRuntimeEntryHelpers = require.resolve(
+ '@babel/runtime/helpers/esm/assertThisInitialized',
+ { paths: [babelRuntimeEntry] }
+);
+const babelRuntimeRegenerator = require.resolve('@babel/runtime/regenerator', {
+ paths: [babelRuntimeEntry],
+});
// 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")
+const imageInlineSizeLimit = parseInt(
+ process.env.IMAGE_INLINE_SIZE_LIMIT || '10000'
+);
// Check if TypeScript is setup
-const useTypeScript = fs.existsSync(paths.appTsConfig)
+const useTypeScript = fs.existsSync(paths.appTsConfig);
+
+// Check if Tailwind config exists
+const useTailwind = fs.existsSync(
+ path.join(paths.appPath, 'tailwind.config.js')
+);
// Get the path to the uncompiled service worker (if it exists).
-const swSrc = paths.swSrc
+const swSrc = paths.swSrc;
// style files regexes
-const cssRegex = /\.css$/
-const cssModuleRegex = /\.module\.css$/
-const sassRegex = /\.(scss|sass)$/
-const sassModuleRegex = /\.module\.(scss|sass)$/
+const cssRegex = /\.css$/;
+const cssModuleRegex = /\.module\.css$/;
+const sassRegex = /\.(scss|sass)$/;
+const sassModuleRegex = /\.module\.(scss|sass)$/;
const hasJsxRuntime = (() => {
- if (process.env.DISABLE_NEW_JSX_TRANSFORM === "true") {
- return false
+ if (process.env.DISABLE_NEW_JSX_TRANSFORM === 'true') {
+ return false;
}
try {
- require.resolve("react/jsx-runtime")
- return true
+ require.resolve('react/jsx-runtime');
+ return true;
} catch (e) {
- return false
+ return false;
}
-})()
+})();
// 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")
+ const isEnvProductionProfile =
+ 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.
// Omit trailing slash as %PUBLIC_URL%/xyz looks better than %PUBLIC_URL%xyz.
// Get environment variables to inject into our app.
- const env = getClientEnvironment(paths.publicUrlOrPath.slice(0, -1))
+ const env = getClientEnvironment(paths.publicUrlOrPath.slice(0, -1));
- const shouldUseReactRefresh = env.raw.FAST_REFRESH
+ const shouldUseReactRefresh = env.raw.FAST_REFRESH;
// 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"),
+ 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: {
+ postcssOptions: {
+ // Necessary for external CSS imports to work
+ // https://github.com/facebook/create-react-app/issues/2677
+ ident: 'postcss',
+ config: false,
+ plugins: !useTailwind
+ ? [
+ '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',
+ ]
+ : [
+ 'tailwindcss',
+ 'postcss-flexbugs-fixes',
+ [
+ 'postcss-preset-env',
+ {
+ autoprefixer: {
+ flexbox: 'no-2009',
+ },
+ stage: 3,
+ },
+ ],
+ ],
+ },
sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment,
},
},
- ].filter(Boolean)
+ ].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,
@@ -121,77 +181,69 @@ module.exports = function (webpackEnv) {
sourceMap: true,
},
}
- )
+ );
}
- return loaders
- }
+ return loaders;
+ };
return {
- mode: isEnvProduction ? "production" : isEnvDevelopment && "development",
- target: "web",
+ target: ['browserslist'],
+ // Webpack noise constrained to errors and warnings
+ stats: 'errors-warnings',
+ mode: isEnvProduction ? 'production' : isEnvDevelopment && 'development',
// Stop compilation early in production
bail: isEnvProduction,
devtool: isEnvProduction
? shouldUseSourceMap
- ? "source-map"
+ ? 'source-map'
: false
- : isEnvDevelopment && "cheap-module-source-map",
+ : 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:
- 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
- // of CSS changes), or refresh the page (in case of JS changes). When you
- // make a syntax error, this client will display a syntax error overlay.
- // Note: instead of the default WebpackDevServer client, we use a custom one
- // to bring better experience for Create React App users. You can replace
- // the line below with these two lines if you prefer the stock client:
- //
- // require.resolve('webpack-dev-server/client') + '?/',
- // require.resolve('webpack/hot/dev-server'),
- //
- // When using the experimental react-refresh integration,
- // the webpack plugin takes care of injecting the dev client for us.
- webpackDevClientEntry,
- // Finally, this is your app's code:
- 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,
+ entry: 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.
// In development, it does not produce real files.
filename: isEnvProduction
- ? "static/js/[name].[contenthash:8].js"
- : isEnvDevelopment && "static/js/[name].bundle.js",
+ ? 'static/js/[name].[contenthash:8].js'
+ : isEnvDevelopment && 'static/js/bundle.js',
// 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",
- assetModuleFilename: "static/media/[name].[hash][ext]",
+ ? 'static/js/[name].[contenthash:8].chunk.js'
+ : isEnvDevelopment && 'static/js/[name].chunk.js',
+ assetModuleFilename: 'static/media/[name].[hash][ext]',
// 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) => path.relative(paths.appSrc, info.absoluteResourcePath).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.
- chunkLoadingGlobal: `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",
+ ? info =>
+ path
+ .relative(paths.appSrc, info.absoluteResourcePath)
+ .replace(/\\/g, '/')
+ : isEnvDevelopment &&
+ (info => path.resolve(info.absoluteResourcePath).replace(/\\/g, '/')),
+ },
+ 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',
},
optimization: {
minimize: isEnvProduction,
@@ -235,42 +287,19 @@ module.exports = function (webpackEnv) {
ascii_only: true,
},
},
- sourceMap: shouldUseSourceMap,
- }),
- new CssMinimizerPlugin({
- minimizerOptions: {
- // Other options are available https://webpack.js.org/plugins/css-minimizer-webpack-plugin/#minify
- preset: [
- "default",
- {
- discardComments: { removeAll: true },
- minifyFontValues: { removeQuotes: false },
- },
- ],
- },
}),
+ // This is only used in production mode
+ 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: 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}`,
- },
},
resolve: {
// 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.additionalModulePaths || []),
- preferRelative: true,
+ modules: ['node_modules', paths.appNodeModules].concat(
+ modules.additionalModulePaths || []
+ ),
// These are the reasonable defaults supported by the Node ecosystem.
// We also include JSX as a common component filename extension to support
// some tools, although we do not recommend using it, see:
@@ -278,96 +307,106 @@ 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 || {}),
},
plugins: [
- // Adds support for installing with Plug'n'Play, leading to faster installs and adding
- // guards against forgotten dependencies and such.
// 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,
// please link the files into your node_modules/ and let module-resolution kick in.
// Make sure your source files are compiled, as they will not be processed in any way.
- new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson, reactRefreshOverlayEntry]),
+ new ModuleScopePlugin(paths.appSrc, [
+ paths.appPackageJson,
+ reactRefreshRuntimeEntry,
+ reactRefreshWebpackPluginRuntimeEntry,
+ babelRuntimeEntry,
+ babelRuntimeEntryHelpers,
+ babelRuntimeRegenerator,
+ ]),
],
+ // VICTRON: BEGIN
// 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.
fallback: {
- module: false,
- dgram: false,
- fs: false,
- http2: false,
- net: false,
- tls: false,
- child_process: false,
- stream: require.resolve("stream-browserify"),
+ 'process/browser': require.resolve('process/browser'),
buffer: require.resolve("buffer"),
- url: require.resolve("url/")
- },
+ }
+ // VICTRON: END
},
module: {
strictExportPresence: true,
rules: [
- // Disable require.ensure as it's not a standard language feature.
- {
- // The new webpack5 parser rules applies both for Js and Json, but Json module
- // hasn't `requireEnsure` parameter in config, therefore we apply this rule only for Js
- test: /\.[cm]?js$/,
- parser: { requireEnsure: false },
+ // Handle node_modules packages that contain sourcemaps
+ shouldUseSourceMap && {
+ enforce: 'pre',
+ exclude: /@babel(?:\/|\\{1,2})runtime/,
+ test: /\.(js|mjs|jsx|ts|tsx|css)$/,
+ loader: require.resolve('source-map-loader'),
},
{
// "oneOf" will traverse all following loaders until one will
// match the requirements. When no loader matches it will fall
// back to the "file" loader at the end of the loader list.
oneOf: [
- {
- test: /\.svg$/,
- // inline SVGs only for Marine2 app
- include: [paths.appSrc + "/app/Marine2"],
- use: [
- { loader: require.resolve("babel-loader") },
- {
- loader: require.resolve("react-svg-loader"),
- options: { jsx: true },
- },
- ],
- },
-
// TODO: Merge this config once `image/avif` is in the mime-db
// 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',
+ parser: {
+ dataUrlCondition: {
+ maxSize: imageInlineSizeLimit,
+ },
},
},
- {
- test: /\.(woff|woff2|eot|ttf|otf)$/i,
- type: "asset/resource",
- },
// "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"),
- options: {
- limit: imageInlineSizeLimit,
- name: "static/media/[name].[hash:8].[ext]",
+ type: 'asset',
+ parser: {
+ dataUrlCondition: {
+ maxSize: imageInlineSizeLimit,
+ },
+ },
+ },
+ {
+ test: /\.svg$/,
+ use: [
+ {
+ loader: require.resolve('@svgr/webpack'),
+ options: {
+ prettier: false,
+ svgo: false,
+ svgoConfig: {
+ plugins: [{ removeViewBox: false }],
+ },
+ titleProp: true,
+ ref: true,
+ },
+ },
+ {
+ loader: require.resolve('file-loader'),
+ options: {
+ name: 'static/media/[name].[hash].[ext]',
+ },
+ },
+ ],
+ issuer: {
+ and: [/\.(ts|tsx|js|jsx|md|mdx)$/],
},
},
// Process application JS with Babel.
@@ -375,32 +414,25 @@ module.exports = function (webpackEnv) {
{
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-app/webpack-overrides"),
+ customize: require.resolve(
+ 'babel-preset-react-app/webpack-overrides'
+ ),
presets: [
[
- require.resolve("babel-preset-react-app"),
+ require.resolve('babel-preset-react-app'),
{
- runtime: hasJsxRuntime ? "automatic" : "classic",
+ runtime: hasJsxRuntime ? 'automatic' : 'classic',
},
],
],
-
+
plugins: [
- [
- require.resolve("babel-plugin-named-asset-import"),
- {
- loaderMap: {
- svg: {
- ReactComponent: "@svgr/webpack?-svgo,+titleProp,+ref![path]",
- },
- },
- },
- ],
- isEnvDevelopment && shouldUseReactRefresh && require.resolve("react-refresh/babel"),
+ 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.
@@ -415,16 +447,21 @@ module.exports = function (webpackEnv) {
{
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: [[require.resolve("babel-preset-react-app/dependencies"), { helpers: true }]],
+ presets: [
+ [
+ require.resolve('babel-preset-react-app/dependencies'),
+ { 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.
@@ -444,7 +481,12 @@ module.exports = function (webpackEnv) {
exclude: cssModuleRegex,
use: getStyleLoaders({
importLoaders: 1,
- sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment,
+ sourceMap: isEnvProduction
+ ? shouldUseSourceMap
+ : isEnvDevelopment,
+ modules: {
+ mode: 'icss',
+ },
}),
// Don't consider CSS imports dead code even if the
// containing package claims to have no side effects.
@@ -458,8 +500,11 @@ module.exports = function (webpackEnv) {
test: cssModuleRegex,
use: getStyleLoaders({
importLoaders: 1,
- sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment,
+ sourceMap: isEnvProduction
+ ? shouldUseSourceMap
+ : isEnvDevelopment,
modules: {
+ mode: 'local',
getLocalIdent: getCSSModuleLocalIdent,
},
}),
@@ -473,9 +518,14 @@ module.exports = function (webpackEnv) {
use: getStyleLoaders(
{
importLoaders: 3,
- sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment,
+ sourceMap: isEnvProduction
+ ? shouldUseSourceMap
+ : isEnvDevelopment,
+ modules: {
+ mode: 'icss',
+ },
},
- "sass-loader"
+ 'sass-loader'
),
// Don't consider CSS imports dead code even if the
// containing package claims to have no side effects.
@@ -490,12 +540,15 @@ module.exports = function (webpackEnv) {
use: getStyleLoaders(
{
importLoaders: 3,
- sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment,
+ sourceMap: isEnvProduction
+ ? shouldUseSourceMap
+ : isEnvDevelopment,
modules: {
+ mode: 'local',
getLocalIdent: getCSSModuleLocalIdent,
},
},
- "sass-loader"
+ 'sass-loader'
),
},
// "file" loader makes sure those assets get served by WebpackDevServer.
@@ -504,21 +557,18 @@ 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]",
- },
+ exclude: [/^$/, /\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/],
+ type: 'asset/resource',
},
// ** STOP ** Are you adding a new loader?
// Make sure to add the new loader(s) before the "file" loader.
],
},
- ],
+ ].filter(Boolean),
},
plugins: [
// Generates an `index.html` file with the