diff --git a/config/env.js b/config/env.js
index 112e360a..f543dfad 100644
--- a/config/env.js
+++ b/config/env.js
@@ -1,5 +1,3 @@
-
-
const fs = require('fs');
const path = require('path');
const paths = require('./paths');
@@ -9,20 +7,20 @@ delete require.cache[require.resolve('./paths')];
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
const dotenvFiles = [
- `${paths.dotenv}.${NODE_ENV}.local`,
- `${paths.dotenv}.${NODE_ENV}`,
- // 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`,
- paths.dotenv,
+ `${paths.dotenv}.${NODE_ENV}.local`,
+ `${paths.dotenv}.${NODE_ENV}`,
+ // 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`,
+ paths.dotenv,
].filter(Boolean);
// Load environment variables from .env* files. Suppress warnings using silent
@@ -31,13 +29,13 @@ const dotenvFiles = [
// https://github.com/motdotla/dotenv
// https://github.com/motdotla/dotenv-expand
dotenvFiles.forEach(dotenvFile => {
- if (fs.existsSync(dotenvFile)) {
- require('dotenv-expand')(
- require('dotenv').config({
- path: dotenvFile,
- })
- );
- }
+ if (fs.existsSync(dotenvFile)) {
+ require('dotenv-expand')(
+ require('dotenv').config({
+ path: dotenvFile,
+ })
+ );
+ }
});
// We support resolving modules according to `NODE_PATH`.
@@ -51,43 +49,43 @@ dotenvFiles.forEach(dotenvFile => {
// 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 || '')
- .split(path.delimiter)
- .filter(folder => folder && !path.isAbsolute(folder))
- .map(folder => path.resolve(appDirectory, folder))
- .join(path.delimiter);
+ .split(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;
function getClientEnvironment(publicUrl) {
- const raw = Object.keys(process.env)
- .filter(key => REACT_APP.test(key))
- .reduce(
- (env, key) => {
- 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',
- // 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
- // images into the `src` and `import` them in code to get their paths.
- PUBLIC_URL: publicUrl,
- }
- );
- // 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;
- }, {}),
- };
+ const raw = Object.keys(process.env)
+ .filter(key => REACT_APP.test(key))
+ .reduce(
+ (env, key) => {
+ 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',
+ // 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
+ // images into the `src` and `import` them in code to get their paths.
+ PUBLIC_URL: publicUrl,
+ }
+ );
+ // 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;
+ }, {}),
+ };
- return { raw, stringified };
+ return { raw, stringified };
}
module.exports = getClientEnvironment;
diff --git a/config/jest/cssTransform.js b/config/jest/cssTransform.js
index d5a7f7f9..3d272ce5 100644
--- a/config/jest/cssTransform.js
+++ b/config/jest/cssTransform.js
@@ -1,14 +1,12 @@
-
-
// 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 = {};';
- },
- getCacheKey() {
- // The output is always the same.
- return 'cssTransform';
- },
+ process() {
+ return 'module.exports = {};';
+ },
+ getCacheKey() {
+ // The output is always the same.
+ return 'cssTransform';
+ },
};
diff --git a/config/jest/fileTransform.js b/config/jest/fileTransform.js
index a71e0d48..82486927 100644
--- a/config/jest/fileTransform.js
+++ b/config/jest/fileTransform.js
@@ -1,5 +1,3 @@
-
-
const path = require('path');
const camelcase = require('camelcase');
@@ -7,17 +5,17 @@ const camelcase = require('camelcase');
// http://facebook.github.io/jest/docs/en/webpack.html
module.exports = {
- process(src, filename) {
- const assetFilename = JSON.stringify(path.basename(filename));
+ process(src, 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}`;
- return `const React = require('react');
+ 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}`;
+ return `const React = require('react');
module.exports = {
__esModule: true,
default: ${assetFilename},
@@ -33,8 +31,8 @@ module.exports = {
};
}),
};`;
- }
+ }
- return `module.exports = ${assetFilename};`;
- },
+ return `module.exports = ${assetFilename};`;
+ },
};
diff --git a/config/modules.js b/config/modules.js
index 1293bca5..351c9cca 100644
--- a/config/modules.js
+++ b/config/modules.js
@@ -1,5 +1,3 @@
-
-
const fs = require('fs');
const path = require('path');
const paths = require('./paths');
@@ -12,48 +10,48 @@ const resolve = require('resolve');
* @param {Object} options
*/
function getAdditionalModulePaths(options = {}) {
- const baseUrl = options.baseUrl;
-
- // We need to explicitly check for null and undefined (and not a falsy value) because
- // TypeScript treats an empty string as `.`.
- if (baseUrl == null) {
- // If there's no baseUrl set we respect NODE_PATH
- // Note that NODE_PATH is deprecated and will be removed
- // in the next major release of create-react-app.
-
- const nodePath = process.env.NODE_PATH || '';
- return nodePath.split(path.delimiter).filter(Boolean);
- }
-
- 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;
- }
-
- // Allow the user set the `baseUrl` to `appSrc`.
- if (path.relative(paths.appSrc, baseUrlResolved) === '') {
- return [paths.appSrc];
- }
-
- // If the path is equal to the root directory we ignore it here.
- // We don't want to allow importing from the root directly as source files are
- // 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;
- }
-
- // 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.'
- )
- );
+ const baseUrl = options.baseUrl;
+
+ // We need to explicitly check for null and undefined (and not a falsy value) because
+ // TypeScript treats an empty string as `.`.
+ if (baseUrl == null) {
+ // If there's no baseUrl set we respect NODE_PATH
+ // Note that NODE_PATH is deprecated and will be removed
+ // in the next major release of create-react-app.
+
+ const nodePath = process.env.NODE_PATH || '';
+ return nodePath.split(path.delimiter).filter(Boolean);
+ }
+
+ 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;
+ }
+
+ // Allow the user set the `baseUrl` to `appSrc`.
+ if (path.relative(paths.appSrc, baseUrlResolved) === '') {
+ return [paths.appSrc];
+ }
+
+ // If the path is equal to the root directory we ignore it here.
+ // We don't want to allow importing from the root directly as source files are
+ // 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;
+ }
+
+ // 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.'
+ )
+ );
}
/**
@@ -62,19 +60,19 @@ function getAdditionalModulePaths(options = {}) {
* @param {*} options
*/
function getWebpackAliases(options = {}) {
- const baseUrl = options.baseUrl;
+ const baseUrl = options.baseUrl;
- if (!baseUrl) {
- return {};
- }
+ if (!baseUrl) {
+ return {};
+ }
- const baseUrlResolved = path.resolve(paths.appPath, baseUrl);
+ const baseUrlResolved = path.resolve(paths.appPath, baseUrl);
- if (path.relative(paths.appPath, baseUrlResolved) === '') {
- return {
- src: paths.appSrc,
- };
- }
+ if (path.relative(paths.appPath, baseUrlResolved) === '') {
+ return {
+ src: paths.appSrc,
+ };
+ }
}
/**
@@ -83,59 +81,59 @@ function getWebpackAliases(options = {}) {
* @param {*} options
*/
function getJestAliases(options = {}) {
- const baseUrl = options.baseUrl;
+ const baseUrl = options.baseUrl;
- if (!baseUrl) {
- return {};
- }
+ if (!baseUrl) {
+ return {};
+ }
- const baseUrlResolved = path.resolve(paths.appPath, baseUrl);
+ const baseUrlResolved = path.resolve(paths.appPath, baseUrl);
- if (path.relative(paths.appPath, baseUrlResolved) === '') {
- return {
- 'src/(.*)$': '/src/$1',
- };
- }
+ if (path.relative(paths.appPath, baseUrlResolved) === '') {
+ return {
+ 'src/(.*)$': '/src/$1',
+ };
+ }
}
function getModules() {
- // Check if TypeScript is setup
- const hasTsConfig = fs.existsSync(paths.appTsConfig);
- const hasJsConfig = fs.existsSync(paths.appJsConfig);
+ // Check if TypeScript is setup
+ 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.'
+ );
+ }
+
+ 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', {
+ basedir: paths.appNodeModules,
+ }));
+ 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 = config || {};
+ const options = config.compilerOptions || {};
+
+ const additionalModulePaths = getAdditionalModulePaths(options);
- 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.'
- );
- }
-
- 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', {
- basedir: paths.appNodeModules,
- }));
- 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 = config || {};
- const options = config.compilerOptions || {};
-
- const additionalModulePaths = getAdditionalModulePaths(options);
-
- return {
- additionalModulePaths: additionalModulePaths,
- webpackAliases: getWebpackAliases(options),
- jestAliases: getJestAliases(options),
- hasTsConfig,
- };
+ return {
+ additionalModulePaths: additionalModulePaths,
+ webpackAliases: getWebpackAliases(options),
+ jestAliases: getJestAliases(options),
+ hasTsConfig,
+ };
}
module.exports = getModules();
diff --git a/config/paths.js b/config/paths.js
index d026ef96..ae7b5240 100644
--- a/config/paths.js
+++ b/config/paths.js
@@ -1,5 +1,3 @@
-
-
const path = require('path');
const fs = require('fs');
const url = require('url');
@@ -12,18 +10,18 @@ const resolveApp = relativePath => path.resolve(appDirectory, relativePath);
const envPublicUrl = process.env.PUBLIC_URL;
function ensureSlash(inputPath, needsSlash) {
- const hasSlash = inputPath.endsWith('/');
- if (hasSlash && !needsSlash) {
- return inputPath.substr(0, inputPath.length - 1);
- } else if (!hasSlash && needsSlash) {
- return `${inputPath}/`;
- } else {
- return inputPath;
- }
+ const hasSlash = inputPath.endsWith('/');
+ if (hasSlash && !needsSlash) {
+ return inputPath.substr(0, inputPath.length - 1);
+ } else if (!hasSlash && needsSlash) {
+ return `${inputPath}/`;
+ } else {
+ return inputPath;
+ }
}
const getPublicUrl = appPackageJson =>
- envPublicUrl || require(appPackageJson).homepage;
+ envPublicUrl || require(appPackageJson).homepage;
// We use `PUBLIC_URL` environment variable or "homepage" field to infer
// "public path" at which the app is served.
@@ -32,59 +30,57 @@ const getPublicUrl = appPackageJson =>
// 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.
function getServedPath(appPackageJson) {
- const publicUrl = getPublicUrl(appPackageJson);
- const servedUrl =
- envPublicUrl || (publicUrl ? url.parse(publicUrl).pathname : '/');
- return ensureSlash(servedUrl, true);
+ const publicUrl = getPublicUrl(appPackageJson);
+ const servedUrl =
+ envPublicUrl || (publicUrl ? url.parse(publicUrl).pathname : '/');
+ return ensureSlash(servedUrl, true);
}
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}`);
- }
+ if (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('.'),
- appBuild: resolveApp('build'),
- 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'),
- publicUrl: getPublicUrl(resolveApp('package.json')),
- servedPath: getServedPath(resolveApp('package.json')),
+ dotenv: resolveApp('.env'),
+ appPath: resolveApp('.'),
+ appBuild: resolveApp('build'),
+ 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'),
+ publicUrl: getPublicUrl(resolveApp('package.json')),
+ servedPath: getServedPath(resolveApp('package.json')),
};
-
-
module.exports.moduleFileExtensions = moduleFileExtensions;
diff --git a/config/pnpTs.js b/config/pnpTs.js
index c5c00921..cf091347 100644
--- a/config/pnpTs.js
+++ b/config/pnpTs.js
@@ -1,35 +1,33 @@
-
-
const { resolveModuleName } = require('ts-pnp');
exports.resolveModuleName = (
- typescript,
- moduleName,
- containingFile,
- compilerOptions,
- resolutionHost
-) => {
- return resolveModuleName(
+ typescript,
moduleName,
containingFile,
compilerOptions,
- resolutionHost,
- typescript.resolveModuleName
- );
+ resolutionHost
+) => {
+ return resolveModuleName(
+ moduleName,
+ containingFile,
+ compilerOptions,
+ resolutionHost,
+ typescript.resolveModuleName
+ );
};
exports.resolveTypeReferenceDirective = (
- typescript,
- moduleName,
- containingFile,
- compilerOptions,
- resolutionHost
-) => {
- return resolveModuleName(
+ typescript,
moduleName,
containingFile,
compilerOptions,
- resolutionHost,
- typescript.resolveTypeReferenceDirective
- );
+ resolutionHost
+) => {
+ return resolveModuleName(
+ moduleName,
+ containingFile,
+ compilerOptions,
+ resolutionHost,
+ typescript.resolveTypeReferenceDirective
+ );
};
diff --git a/config/webpack.config.js b/config/webpack.config.js
index dc371f30..6d53fb37 100644
--- a/config/webpack.config.js
+++ b/config/webpack.config.js
@@ -1,5 +1,3 @@
-
-
const fs = require('fs');
const isWsl = require('is-wsl');
const path = require('path');
@@ -38,7 +36,7 @@ const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';
const shouldInlineRuntimeChunk = process.env.INLINE_RUNTIME_CHUNK !== 'false';
const imageInlineSizeLimit = parseInt(
- process.env.IMAGE_INLINE_SIZE_LIMIT || '10000'
+ process.env.IMAGE_INLINE_SIZE_LIMIT || '10000'
);
// Check if TypeScript is setup
@@ -53,628 +51,653 @@ const sassModuleRegex = /\.module\.(scss|sass)$/;
// 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');
+ // 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');
- // 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.
- // In development, we always serve from the root. This makes config easier.
- const publicPath = isEnvProduction
- ? paths.servedPath
- : isEnvDevelopment && '/';
- // Some apps do not use client-side routing with pushState.
- // For these, "homepage" can be set to "." to enable relative asset paths.
- const shouldUseRelativeAssetPaths = publicPath === './';
+ // 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.
+ // In development, we always serve from the root. This makes config easier.
+ const publicPath = isEnvProduction
+ ? paths.servedPath
+ : isEnvDevelopment && '/';
+ // Some apps do not use client-side routing with pushState.
+ // For these, "homepage" can be set to "." to enable relative asset paths.
+ const shouldUseRelativeAssetPaths = publicPath === './';
- // `publicUrl` is just like `publicPath`, but we will provide it 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.
- const publicUrl = isEnvProduction
- ? publicPath.slice(0, -1)
- : isEnvDevelopment && '';
- // Get environment variables to inject into our app.
- const env = getClientEnvironment(publicUrl);
-
- // common function to get style loaders
- const getStyleLoaders = (cssOptions, preProcessor) => {
- const loaders = [
- isEnvDevelopment && require.resolve('style-loader'),
- isEnvProduction && {
- loader: MiniCssExtractPlugin.loader,
- options: shouldUseRelativeAssetPaths ? { publicPath: '../../' } : {},
- },
- {
- 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'),
- 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,
- },
- },
- ].filter(Boolean);
- if (preProcessor) {
- loaders.push(
- {
- loader: require.resolve('resolve-url-loader'),
- options: {
- sourceMap: isEnvProduction && shouldUseSourceMap,
- },
- },
- {
- loader: require.resolve(preProcessor),
- options: {
- sourceMap: true,
- },
- }
- );
- }
- return loaders;
- };
+ // `publicUrl` is just like `publicPath`, but we will provide it 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.
+ const publicUrl = isEnvProduction
+ ? publicPath.slice(0, -1)
+ : isEnvDevelopment && '';
+ // Get environment variables to inject into our app.
+ const env = getClientEnvironment(publicUrl);
- return {
- mode: isEnvProduction ? 'production' : isEnvDevelopment && 'development',
- // Stop compilation early in production
- bail: isEnvProduction,
- devtool: isEnvProduction
- ? 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: [
- // 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'),
- isEnvDevelopment &&
- require.resolve('react-dev-utils/webpackHotDevClient'),
- // 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.
- ].filter(Boolean),
- output: {
- // The build folder.
- path: isEnvProduction ? paths.appBuild : undefined,
- // 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/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'
- : isEnvDevelopment && 'static/js/[name].chunk.js',
- // We inferred the "public path" (such as / or /my-project) from homepage.
- // We use "/" in development.
- publicPath: publicPath,
- // 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.
- 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',
- },
- optimization: {
- minimize: isEnvProduction,
- minimizer: [
- // This is only used in production mode
- new TerserPlugin({
- terserOptions: {
- parse: {
- // We want terser to parse ecma 8 code. However, we don't want it
- // to apply any minification steps that turns valid ecma 5 code
- // 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,
- },
- compress: {
- ecma: 5,
- warnings: false,
- // Disabled because of an issue with Uglify breaking seemingly valid code:
- // https://github.com/facebook/create-react-app/issues/2376
- // Pending further investigation:
- // https://github.com/mishoo/UglifyJS2/issues/2011
- comparisons: false,
- // Disabled because of an issue with Terser breaking valid code:
- // https://github.com/facebook/create-react-app/issues/5250
- // Pending further investigation:
- // https://github.com/terser-js/terser/issues/120
- inline: 2,
+ // common function to get style loaders
+ const getStyleLoaders = (cssOptions, preProcessor) => {
+ const loaders = [
+ isEnvDevelopment && require.resolve('style-loader'),
+ isEnvProduction && {
+ loader: MiniCssExtractPlugin.loader,
+ options: shouldUseRelativeAssetPaths
+ ? { publicPath: '../../' }
+ : {},
},
- mangle: {
- safari10: true,
+ {
+ loader: require.resolve('css-loader'),
+ options: cssOptions,
},
- // Added for profiling in devtools
- keep_classnames: isEnvProductionProfile,
- keep_fnames: isEnvProductionProfile,
- output: {
- ecma: 5,
- 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,
+ {
+ // 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'),
+ 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,
+ },
},
- },
- // Use multi-process parallel running to improve the build speed
- // Default number of concurrent runs: os.cpus().length - 1
- // Disabled on WSL (Windows Subsystem for Linux) due to an issue with Terser
- // https://github.com/webpack-contrib/terser-webpack-plugin/issues/21
- parallel: !isWsl,
- // Enable file caching
- cache: true,
- 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,
+ ].filter(Boolean);
+ if (preProcessor) {
+ loaders.push(
+ {
+ loader: require.resolve('resolve-url-loader'),
+ options: {
+ sourceMap: isEnvProduction && shouldUseSourceMap,
+ },
+ },
+ {
+ loader: require.resolve(preProcessor),
+ options: {
+ sourceMap: true,
+ },
}
- : 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: 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 || []
- ),
- // 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:
- // https://github.com/facebook/create-react-app/issues/290
- // `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')),
- 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',
- // Allows for better profiling with ReactDevTools
- ...(isEnvProductionProfile && {
- '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.
- 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,
- // 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]),
- ],
- },
- 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: [
- // Disable require.ensure as it's not a standard language feature.
- { parser: { requireEnsure: false } },
+ );
+ }
+ return loaders;
+ };
- // First, run the linter.
- // It's important to do this before Babel processes the JS.
- {
- test: /\.(js|mjs|jsx|ts|tsx)$/,
- enforce: 'pre',
- use: [
- {
- options: {
- cache: true,
- formatter: require.resolve('react-dev-utils/eslintFormatter'),
- eslintPath: require.resolve('eslint'),
- resolvePluginsRelativeTo: __dirname,
-
- },
- loader: require.resolve('eslint-loader'),
- },
- ],
- include: paths.appSrc,
+ return {
+ mode: isEnvProduction
+ ? 'production'
+ : isEnvDevelopment && 'development',
+ // Stop compilation early in production
+ bail: isEnvProduction,
+ devtool: isEnvProduction
+ ? 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: [
+ // 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'),
+ isEnvDevelopment &&
+ require.resolve('react-dev-utils/webpackHotDevClient'),
+ // 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.
+ ].filter(Boolean),
+ output: {
+ // The build folder.
+ path: isEnvProduction ? paths.appBuild : undefined,
+ // 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/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'
+ : isEnvDevelopment && 'static/js/[name].chunk.js',
+ // We inferred the "public path" (such as / or /my-project) from homepage.
+ // We use "/" in development.
+ publicPath: publicPath,
+ // 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.
+ 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',
},
- {
- // "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: [
- // "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]',
- },
- },
- // 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'),
- options: {
- customize: require.resolve(
- 'babel-preset-react-app/webpack-overrides'
- ),
-
- plugins: [
- [
- require.resolve('babel-plugin-named-asset-import'),
- {
- loaderMap: {
- svg: {
- ReactComponent:
- '@svgr/webpack?-svgo,+titleProp,+ref![path]',
+ optimization: {
+ minimize: isEnvProduction,
+ minimizer: [
+ // This is only used in production mode
+ new TerserPlugin({
+ terserOptions: {
+ parse: {
+ // We want terser to parse ecma 8 code. However, we don't want it
+ // to apply any minification steps that turns valid ecma 5 code
+ // 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,
+ },
+ compress: {
+ ecma: 5,
+ warnings: false,
+ // Disabled because of an issue with Uglify breaking seemingly valid code:
+ // https://github.com/facebook/create-react-app/issues/2376
+ // Pending further investigation:
+ // https://github.com/mishoo/UglifyJS2/issues/2011
+ comparisons: false,
+ // Disabled because of an issue with Terser breaking valid code:
+ // https://github.com/facebook/create-react-app/issues/5250
+ // Pending further investigation:
+ // https://github.com/terser-js/terser/issues/120
+ inline: 2,
+ },
+ mangle: {
+ safari10: true,
+ },
+ // Added for profiling in devtools
+ keep_classnames: isEnvProductionProfile,
+ keep_fnames: isEnvProductionProfile,
+ output: {
+ ecma: 5,
+ 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,
},
- },
},
- ],
- ],
- // 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,
- },
+ // Use multi-process parallel running to improve the build speed
+ // Default number of concurrent runs: os.cpus().length - 1
+ // Disabled on WSL (Windows Subsystem for Linux) due to an issue with Terser
+ // https://github.com/webpack-contrib/terser-webpack-plugin/issues/21
+ parallel: !isWsl,
+ // Enable file caching
+ cache: true,
+ 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,
+ },
+ }),
+ ],
+ // 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,
},
- // 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'),
- 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,
-
- // If an error happens in a package, it's possible to be
- // because it was compiled. Thus, we don't want the browser
- // debugger to show the original code. Instead, the code
- // being evaluated would be much more helpful.
- sourceMaps: 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}`,
},
- // "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