diff --git a/packages/react-scripts/README.md b/packages/react-scripts/README.md
index 357131f0e80..eb4dda1d05b 100644
--- a/packages/react-scripts/README.md
+++ b/packages/react-scripts/README.md
@@ -1,7 +1,25 @@
-# react-scripts
+# byted-react-scripts
-This package includes scripts and configuration used by [Create React App](https://github.com/facebook/create-react-app).
+__usage:__
+
+```sh
+create-react-app --scripts-version=byted-react-scripts
+```
+
+
+
+This package includes scripts and configuration forked from [Create React App](https://github.com/facebook/create-react-app).
Please refer to its documentation:
-- [Getting Started](https://github.com/facebook/create-react-app/blob/master/README.md#getting-started) – How to create a new app.
-- [User Guide](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md) – How to develop apps bootstrapped with Create React App.
+* [Getting Started](https://github.com/facebook/create-react-app/blob/master/README.md#getting-started) – How to create a new app.
+* [User Guide](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md) – How to develop apps bootstrapped with Create React App.
+
+## .env config
+ - REACT_APP_REM_UNIT={number}
+ use px2rem
+
+- REACT_APP_HTML_INJECT
+
+ default: true
+
+ inject webpack assets into HTML template
\ No newline at end of file
diff --git a/packages/react-scripts/config/env.js b/packages/react-scripts/config/env.js
index 7565cecd001..1e9316d0ca8 100644
--- a/packages/react-scripts/config/env.js
+++ b/packages/react-scripts/config/env.js
@@ -30,7 +30,7 @@ var dotenvFiles = [
// since normally you expect tests to produce the same
// results for everyone
NODE_ENV !== 'test' && `${paths.dotenv}.local`,
- paths.dotenv,
+ paths.dotenv
].filter(Boolean);
// Load environment variables from .env* files. Suppress warnings using silent
@@ -42,7 +42,7 @@ dotenvFiles.forEach(dotenvFile => {
if (fs.existsSync(dotenvFile)) {
require('dotenv-expand')(
require('dotenv').config({
- path: dotenvFile,
+ path: dotenvFile
})
);
}
@@ -84,7 +84,7 @@ function getClientEnvironment(publicUrl) {
// 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,
+ PUBLIC_URL: publicUrl
}
);
// Stringify all values so we can feed into Webpack DefinePlugin
@@ -92,7 +92,7 @@ function getClientEnvironment(publicUrl) {
'process.env': Object.keys(raw).reduce((env, key) => {
env[key] = JSON.stringify(raw[key]);
return env;
- }, {}),
+ }, {})
};
return { raw, stringified };
diff --git a/packages/react-scripts/config/getWebpackInjectOption.js b/packages/react-scripts/config/getWebpackInjectOption.js
new file mode 100644
index 00000000000..732b37bcc76
--- /dev/null
+++ b/packages/react-scripts/config/getWebpackInjectOption.js
@@ -0,0 +1,12 @@
+'use strict';
+module.exports = function getHtmlWebpackPluginInjectOption(env) {
+ const v = env.raw.REACT_APP_HTML_INJECT;
+ switch (true) {
+ case v === 'head' || v === 'body':
+ return v;
+ case v === 'false':
+ return false;
+ default:
+ return true;
+ }
+};
diff --git a/packages/react-scripts/config/jest/babelTransform.js b/packages/react-scripts/config/jest/babelTransform.js
index 7feed94c59a..890f0a2f127 100644
--- a/packages/react-scripts/config/jest/babelTransform.js
+++ b/packages/react-scripts/config/jest/babelTransform.js
@@ -12,5 +12,5 @@ const babelJest = require('babel-jest');
module.exports = babelJest.createTransformer({
presets: [require.resolve('babel-preset-react-app')],
babelrc: false,
- configFile: false,
+ configFile: false
});
diff --git a/packages/react-scripts/config/jest/cssTransform.js b/packages/react-scripts/config/jest/cssTransform.js
index 59053068f61..303852977b7 100644
--- a/packages/react-scripts/config/jest/cssTransform.js
+++ b/packages/react-scripts/config/jest/cssTransform.js
@@ -18,5 +18,5 @@ module.exports = {
getCacheKey() {
// The output is always the same.
return 'cssTransform';
- },
+ }
};
diff --git a/packages/react-scripts/config/jest/fileTransform.js b/packages/react-scripts/config/jest/fileTransform.js
index f442f0bbd86..d24a2c53b94 100644
--- a/packages/react-scripts/config/jest/fileTransform.js
+++ b/packages/react-scripts/config/jest/fileTransform.js
@@ -34,5 +34,5 @@ module.exports = {
}
return `module.exports = ${assetFilename};`;
- },
+ }
};
diff --git a/packages/react-scripts/config/jest/graphqlTransform.js b/packages/react-scripts/config/jest/graphqlTransform.js
new file mode 100644
index 00000000000..5b70f07d6f2
--- /dev/null
+++ b/packages/react-scripts/config/jest/graphqlTransform.js
@@ -0,0 +1,18 @@
+// @remove-on-eject-begin
+/**
+ * Copyright (c) 2018-present, Facebook, Inc.
+ * Copyright (c) 2016 Remind
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+// @remove-on-eject-end
+'use strict';
+
+const loader = require('graphql-tag/loader');
+
+module.exports = {
+ process(src) {
+ return loader.call({ cacheable() {} }, src);
+ },
+};
diff --git a/packages/react-scripts/config/jest/typescriptTransform.js b/packages/react-scripts/config/jest/typescriptTransform.js
new file mode 100644
index 00000000000..e1a53374f80
--- /dev/null
+++ b/packages/react-scripts/config/jest/typescriptTransform.js
@@ -0,0 +1,7 @@
+// Copyright 2004-present Facebook. All Rights Reserved.
+
+'use strict';
+
+const tsJest = require('ts-jest');
+
+module.exports = tsJest;
diff --git a/packages/react-scripts/config/paths.js b/packages/react-scripts/config/paths.js
index b719054583b..8a7f85b37eb 100644
--- a/packages/react-scripts/config/paths.js
+++ b/packages/react-scripts/config/paths.js
@@ -57,7 +57,7 @@ const moduleFileExtensions = [
'tsx',
'json',
'web.jsx',
- 'jsx',
+ 'jsx'
];
// Resolve file paths in the same order as webpack
@@ -81,15 +81,19 @@ module.exports = {
appPublic: resolveApp('public'),
appHtml: resolveApp('public/index.html'),
appIndexJs: resolveModule(resolveApp, 'src/index'),
+ appIndexJsSSR: resolveModule(resolveApp, 'src/ssr'),
appPackageJson: resolveApp('package.json'),
appSrc: resolveApp('src'),
appTsConfig: resolveApp('tsconfig.json'),
+ appTsProdConfig: resolveApp('tsconfig.prod.json'),
+ appTsSSRConfig: resolveApp('tsconfig.ssr.json'),
+ appTsLint: resolveApp('tslint.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')),
+ servedPath: getServedPath(resolveApp('package.json'))
};
// @remove-on-eject-begin
@@ -103,9 +107,14 @@ module.exports = {
appPublic: resolveApp('public'),
appHtml: resolveApp('public/index.html'),
appIndexJs: resolveModule(resolveApp, 'src/index'),
+ appIndexJsSSR: resolveModule(resolveApp, 'src/ssr'),
appPackageJson: resolveApp('package.json'),
appSrc: resolveApp('src'),
appTsConfig: resolveApp('tsconfig.json'),
+ appTsTestConfig: resolveApp('tsconfig.test.json'),
+ appTsProdConfig: resolveApp('tsconfig.prod.json'),
+ appTsSSRConfig: resolveApp('tsconfig.ssr.json'),
+ appTsLint: resolveApp('tslint.json'),
yarnLockFile: resolveApp('yarn.lock'),
testsSetup: resolveModule(resolveApp, 'src/setupTests'),
proxySetup: resolveApp('src/setupProxy.js'),
@@ -137,6 +146,7 @@ if (
appPublic: resolveOwn('template/public'),
appHtml: resolveOwn('template/public/index.html'),
appIndexJs: resolveModule(resolveOwn, 'template/src/index'),
+ appIndexJsSSR: resolveModule(resolveOwn, 'template/src/ssr'),
appPackageJson: resolveOwn('package.json'),
appSrc: resolveOwn('template/src'),
appTsConfig: resolveOwn('template/tsconfig.json'),
@@ -144,6 +154,11 @@ if (
testsSetup: resolveModule(resolveOwn, 'template/src/setupTests'),
proxySetup: resolveOwn('template/src/setupProxy.js'),
appNodeModules: resolveOwn('node_modules'),
+ appTsConfig: resolveOwn('template/tsconfig.json'),
+ appTsProdConfig: resolveOwn('template/tsconfig.prod.json'),
+ appTsLint: resolveOwn('template/tslint.json'),
+ appTsTestConfig: resolveOwn('template/tsconfig.test.json'),
+ appTsSSRConfig: resolveOwn('template/tsconfig.ssr.json'),
publicUrl: getPublicUrl(resolveOwn('package.json')),
servedPath: getServedPath(resolveOwn('package.json')),
// These properties only exist before ejecting:
diff --git a/packages/react-scripts/config/ssr/DevRebuildPlugin.js b/packages/react-scripts/config/ssr/DevRebuildPlugin.js
new file mode 100644
index 00000000000..05d844b9ab8
--- /dev/null
+++ b/packages/react-scripts/config/ssr/DevRebuildPlugin.js
@@ -0,0 +1,52 @@
+/* eslint-disable */
+const fork = require('child_process').fork;
+const path = require('path');
+const paths = require('../paths');
+const fs = require('fs');
+
+module.exports = class SSRDevRebuilder {
+ apply(compiler) {
+ compiler.plugin('emit', (compilation, callback) => {
+ // var changedFiles = Object.keys(
+ // compilation.fileTimestamps
+ // ).filter(watchfile => {
+ // return (
+ // (this.prevTimestamps[watchfile] || this.startTime) <
+ // (compilation.fileTimestamps[watchfile] || Infinity)
+ // );
+ // });
+
+ let ssrDefer = { resolve: null, reject: null, promise: null };
+ ssrDefer.promise = new Promise((r, j) => {
+ ssrDefer.resolve = r;
+ ssrDefer.reject = j;
+ });
+
+ if (fs.existsSync(paths.appIndexJsSSR)) {
+ console.log('Creating ssr bundle...');
+ const ssrCP = fork(
+ path.resolve(__dirname, '../webpack.config.ssr'),
+ [],
+ {
+ stdio: 'inherit',
+ env: process.env
+ }
+ );
+
+ ssrCP.once('error', err => {
+ console.log(err);
+ ssrDefer.resolve();
+ ssrCP.removeAllListeners('exit');
+ });
+ ssrCP.once('exit', () => {
+ ssrDefer.resolve();
+ });
+ } else {
+ ssrDefer.resolve();
+ }
+
+ this.prevTimestamps = compilation.fileTimestamps;
+ ssrDefer.promise.then(callback);
+ });
+ }
+};
diff --git a/packages/react-scripts/config/ssr/style-loader.js b/packages/react-scripts/config/ssr/style-loader.js
new file mode 100644
index 00000000000..e2f02cbc585
--- /dev/null
+++ b/packages/react-scripts/config/ssr/style-loader.js
@@ -0,0 +1,4 @@
+/* eslint-disable */
+module.exports = function(_source, _map) {
+ return 'export default "";';
+};
diff --git a/packages/react-scripts/config/webpack.base.js b/packages/react-scripts/config/webpack.base.js
new file mode 100644
index 00000000000..d11564bb99d
--- /dev/null
+++ b/packages/react-scripts/config/webpack.base.js
@@ -0,0 +1,255 @@
+'use strict';
+
+const paths = require('./paths');
+const MiniCssExtractPlugin = require('mini-css-extract-plugin');
+const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent');
+const isProduction = process.env.NODE_ENV === 'production';
+const happyPack = process.env.HAPPY_PACK === 'true';
+const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';
+const getClientEnvironment = require('./env');
+const env = getClientEnvironment('');
+// @remove-on-eject-begin
+const getCacheIdentifier = require('react-dev-utils/getCacheIdentifier');
+// @remove-on-eject-end
+
+let cssType = 'sass';
+// 因为目前项目大多用的 sass 预处理,所以优先判断 sass 兼容
+try {
+ require.resolve('less-loader');
+ cssType = 'less';
+} catch (e) {
+ void 0;
+}
+
+// const useTypeScript = fs.existsSync(paths.appTsConfig);
+
+function getStyleLoader(options) {
+ const isLess = options && options.cssType === 'less';
+ const isSass = options && options.cssType === 'sass';
+ const isModules = options && options.modules;
+
+ let styleRegex = /\.css$/;
+ let styleModuleRegex = /\.module\.css$/;
+ if (isSass) {
+ styleRegex = /\.(scss|sass)$/;
+ styleModuleRegex = /\.module\.(scss|sass)$/;
+ } else if (isLess) {
+ styleRegex = /\.less$/;
+ styleModuleRegex = /\.module\.less$/;
+ }
+
+ const styleLoader = require.resolve('style-loader');
+
+ const miniCss = MiniCssExtractPlugin.loader;
+
+ const cssLoader = {
+ loader: require.resolve('css-loader'),
+ options: {
+ importLoaders: isLess || isSass ? 2 : 1
+ }
+ };
+ if (isModules) {
+ cssLoader.options.modules = true;
+ cssLoader.options.getLocalIdent = getCSSModuleLocalIdent;
+ }
+
+ const postCssLoader = {
+ loader: require.resolve('postcss-loader'),
+ options: {
+ ident: 'postcss',
+ plugins: () =>
+ [
+ require('postcss-flexbugs-fixes'),
+ require('postcss-preset-env')({
+ autoprefixer: {
+ flexbox: 'no-2009'
+ },
+ stage: 3
+ }),
+ env.raw.REACT_APP_REM_UNIT &&
+ require('postcss-px2rem')({
+ remUnit: env.raw.REACT_APP_REM_UNIT
+ })
+ ].filter(Boolean),
+ sourceMap: shouldUseSourceMap
+ }
+ };
+
+ const loaders = [
+ isProduction ? miniCss : styleLoader,
+ cssLoader,
+ postCssLoader
+ ];
+
+ if (isSass) {
+ loaders.push({
+ loader: require.resolve('sass-loader'),
+ options: {
+ sourceMap: shouldUseSourceMap
+ }
+ });
+ } else if (isLess) {
+ loaders.push({
+ loader: require.resolve('less-loader'),
+ options: {
+ sourceMap: shouldUseSourceMap
+ }
+ });
+ }
+
+ return {
+ test: isModules ? styleModuleRegex : styleRegex,
+ exclude: isModules ? '//' : styleModuleRegex,
+ use: loaders
+ };
+}
+
+module.exports.loaders = [
+ // "url" loader works just like "file" loader but it also embeds
+ // assets smaller than specified size as data URLs to avoid requests.
+ {
+ test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
+ loader: require.resolve('url-loader'),
+ options: {
+ limit: 10000,
+ name: 'static/media/[name].[hash:8].[ext]'
+ }
+ },
+ // Process JS
+ {
+ test: /\.(js|mjs|jsx)$/,
+ include: paths.appSrc,
+ loader: require.resolve('babel-loader'),
+ options: {
+ customize: require.resolve('babel-preset-react-app/webpack-overrides'),
+ // @remove-on-eject-begin
+ babelrc: false,
+ configFile: false,
+ presets: [require.resolve('babel-preset-react-app')],
+ // Make sure we have a unique cache identifier, erring on the
+ // side of caution.
+ // We remove this when the user ejects because the default
+ // is sane and uses Babel options. Instead of options, we use
+ // the react-scripts and babel-preset-react-app versions.
+ cacheIdentifier: getCacheIdentifier('development', [
+ 'babel-plugin-named-asset-import',
+ 'babel-preset-react-app',
+ 'react-dev-utils',
+ 'react-scripts'
+ ]),
+ // @remove-on-eject-end
+ plugins: [
+ [
+ require.resolve('babel-plugin-named-asset-import'),
+ {
+ loaderMap: {
+ svg: {
+ ReactComponent: '@svgr/webpack?-prettier,-svgo![path]'
+ }
+ }
+ }
+ ]
+ ],
+ // 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,
+ // Don't waste time on Gzipping the cache
+ cacheCompression: 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,
+ // Don't waste time on Gzipping the cache
+ cacheCompression: false,
+ // @remove-on-eject-begin
+ cacheIdentifier: getCacheIdentifier('development', [
+ 'babel-plugin-named-asset-import',
+ 'babel-preset-react-app',
+ 'react-dev-utils',
+ 'react-scripts'
+ ]),
+ // 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.
+ // @remove-on-eject-end
+ sourceMaps: false
+ }
+ },
+ // Process TypeScript
+ {
+ test: /\.tsx?$/,
+ include: paths.srcPaths,
+ exclude: /[\\/]node_modules[\\/]/,
+ use: [
+ {
+ loader: require.resolve('babel-loader'),
+ options: {
+ plugins: [
+ require.resolve('@babel/plugin-syntax-dynamic-import'),
+ [
+ require.resolve('babel-plugin-named-asset-import'),
+ {
+ loaderMap: {
+ svg: {
+ ReactComponent: '@svgr/webpack?-prettier,-svgo![path]'
+ }
+ }
+ }
+ ]
+ ],
+ cacheDirectory: true,
+ cacheCompression: false
+ }
+ },
+ {
+ loader: require.resolve('ts-loader'),
+ options: {
+ happyPackMode: happyPack,
+ getCustomTransformers: require.resolve('./webpack.ts-transformers.js')
+ }
+ }
+ ]
+ },
+ // Process Css
+ getStyleLoader(),
+ // Process Less|Sass
+ getStyleLoader({ cssType }),
+ // Process Css Modules
+ getStyleLoader({ modules: true }),
+ // Process Less|Sass Modules
+ getStyleLoader({ cssType, modules: true }),
+ // "file" loader makes sure assets end up in the `build` folder.
+ // When you `import` an asset, you get its filename.
+ // 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` and `ts` files to keep "css" loader working as it injects
+ // it's 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|jsx|mjs)$/, /\.(ts|tsx)$/, /\.html$/, /\.json$/],
+ options: {
+ 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.
+];
diff --git a/packages/react-scripts/config/webpack.config.dev.js b/packages/react-scripts/config/webpack.config.dev.js
new file mode 100644
index 00000000000..34773962cd3
--- /dev/null
+++ b/packages/react-scripts/config/webpack.config.dev.js
@@ -0,0 +1,228 @@
+// @remove-on-eject-begin
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+// @remove-on-eject-end
+'use strict';
+
+const fs = require('fs');
+const path = require('path');
+const resolve = require('resolve');
+const webpack = require('webpack');
+const PnpWebpackPlugin = require('pnp-webpack-plugin');
+const HtmlWebpackPlugin = require('html-webpack-plugin');
+const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
+const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
+const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
+const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
+const getClientEnvironment = require('./env');
+const paths = require('./paths');
+const ManifestPlugin = require('webpack-manifest-plugin');
+// const ModuleNotFoundPlugin = require('react-dev-utils/ModuleNotFoundPlugin');
+const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin-alt');
+const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
+const { loaders } = require('./webpack.base');
+const getWebpackInjectOption = require('./getWebpackInjectOption');
+// Webpack uses `publicPath` to determine where the app is being served from.
+// In development, we always serve from the root. This makes config easier.
+const 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_PATH%/xyz looks better than %PUBLIC_PATH%xyz.
+const publicUrl = '';
+// Get environment variables to inject into our app.
+const env = getClientEnvironment(publicUrl);
+// When true reduce polyfill bundle size.
+const modernBrowserOnly = process.env.MODERN_BROWSER_ONLY === 'true';
+
+// Check if TypeScript is setup
+const useTypeScript = fs.existsSync(paths.appTsConfig);
+// This is the development configuration.
+// It is focused on developer experience and fast rebuilds.
+// The production configuration is different and lives in a separate file.
+module.exports = {
+ mode: 'development',
+ // You may want 'eval' instead if you prefer to see the compiled output in DevTools.
+ // See the discussion in https://github.com/facebook/create-react-app/issues/343
+ devtool: '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'),
+ 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.
+ ],
+ output: {
+ // Add /* filename */ comments to generated require()s in the output.
+ pathinfo: true,
+ // This does not produce a real file. It's just the virtual path that is
+ // served by WebpackDevServer in development. This is the JS bundle
+ // containing code from all our entry points, and the Webpack runtime.
+ filename: 'static/js/bundle.js',
+ // There are also additional JS chunk files if you use code splitting.
+ chunkFilename: 'static/js/[name].chunk.js',
+ // This is the URL that app is served from. We use "/" in development.
+ publicPath: publicPath,
+ // Point sourcemap entries to original disk location (format as URL on Windows)
+ devtoolModuleFilenameTemplate: info =>
+ path.resolve(info.absoluteResourcePath).replace(/\\/g, '/')
+ },
+ optimization: {
+ // 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: true
+ },
+ // Keep the runtime chunk seperated to enable long term caching
+ // https://twitter.com/wSokra/status/969679223278505985
+ runtimeChunk: false
+ },
+ 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'].concat(
+ // It is guaranteed to exist because we tweak it in `env.js`
+ process.env.NODE_PATH.split(path.delimiter).filter(Boolean)
+ ),
+ // 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: Object.assign(
+ {},
+ modernBrowserOnly
+ ? undefined
+ : {
+ '@babel/runtime': path.dirname(
+ require.resolve('@babel/runtime/package.json')
+ )
+ },
+ {
+ // 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'
+ }
+ ),
+ 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]),
+ useTypeScript &&
+ new TsconfigPathsPlugin({ configFile: paths.appTsConfig })
+ ].filter(Boolean)
+ },
+ 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 } },
+
+ { oneOf: loaders }
+ ]
+ },
+ plugins: [
+ // Generates an `index.html` file with the