@samitouri / QOS-React-2 / commits / 59fd09cb67

[Flight] Add webpack plugin build (#18485)

* Eject CRA from Flight We need to eject because we're going to add a custom Webpack Plugin. We can undo this once the plugin has upstreamed into CRA. * Add Webpack plugin build I call this entry point "webpack-plugin" instead of "plugin" even though this is a webpack specific package. That's because there will also be a Node.js plugin to do the server transform. * Add Flight Webpack plugin to fixture * Rm UMD builds * Transform classes * Rename webpack-plugin to plugin This avoids the double webpack name. We're going to reuse this for both server and client.

Sebastian Markbåge committed Apr 3, 2020 at 14:04 UTC 59fd09cb67c92a89aebc4c0e962f43c0bc0ec6ad
18 files changed +1759 -70
fixtures/flight/config/env.js new
+93
@@ -0,0 +1,93 @@
1 +'use strict';
2 +
3 +const fs = require('fs');
4 +const path = require('path');
5 +const paths = require('./paths');
6 +
7 +// Make sure that including paths.js after env.js will read .env variables.
8 +delete require.cache[require.resolve('./paths')];
9 +
10 +const NODE_ENV = process.env.NODE_ENV;
11 +if (!NODE_ENV) {
12 + throw new Error(
13 + 'The NODE_ENV environment variable is required but was not specified.'
14 + );
15 +}
16 +
17 +// https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use
18 +const dotenvFiles = [
19 + `${paths.dotenv}.${NODE_ENV}.local`,
20 + `${paths.dotenv}.${NODE_ENV}`,
21 + // Don't include `.env.local` for `test` environment
22 + // since normally you expect tests to produce the same
23 + // results for everyone
24 + NODE_ENV !== 'test' && `${paths.dotenv}.local`,
25 + paths.dotenv,
26 +].filter(Boolean);
27 +
28 +// Load environment variables from .env* files. Suppress warnings using silent
29 +// if this file is missing. dotenv will never modify any environment variables
30 +// that have already been set. Variable expansion is supported in .env files.
31 +// https://github.com/motdotla/dotenv
32 +// https://github.com/motdotla/dotenv-expand
33 +dotenvFiles.forEach(dotenvFile => {
34 + if (fs.existsSync(dotenvFile)) {
35 + require('dotenv-expand')(
36 + require('dotenv').config({
37 + path: dotenvFile,
38 + })
39 + );
40 + }
41 +});
42 +
43 +// We support resolving modules according to `NODE_PATH`.
44 +// This lets you use absolute paths in imports inside large monorepos:
45 +// https://github.com/facebook/create-react-app/issues/253.
46 +// It works similar to `NODE_PATH` in Node itself:
47 +// https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders
48 +// Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored.
49 +// Otherwise, we risk importing Node.js core modules into an app instead of Webpack shims.
50 +// https://github.com/facebook/create-react-app/issues/1023#issuecomment-265344421
51 +// We also resolve them to make sure all tools using them work consistently.
52 +const appDirectory = fs.realpathSync(process.cwd());
53 +process.env.NODE_PATH = (process.env.NODE_PATH || '')
54 + .split(path.delimiter)
55 + .filter(folder => folder && !path.isAbsolute(folder))
56 + .map(folder => path.resolve(appDirectory, folder))
57 + .join(path.delimiter);
58 +
59 +// Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be
60 +// injected into the application via DefinePlugin in Webpack configuration.
61 +const REACT_APP = /^REACT_APP_/i;
62 +
63 +function getClientEnvironment(publicUrl) {
64 + const raw = Object.keys(process.env)
65 + .filter(key => REACT_APP.test(key))
66 + .reduce(
67 + (env, key) => {
68 + env[key] = process.env[key];
69 + return env;
70 + },
71 + {
72 + // Useful for determining whether we’re running in production mode.
73 + // Most importantly, it switches React into the correct mode.
74 + NODE_ENV: process.env.NODE_ENV || 'development',
75 + // Useful for resolving the correct path to static assets in `public`.
76 + // For example, <img src={process.env.PUBLIC_URL + '/img/logo.png'} />.
77 + // This should only be used as an escape hatch. Normally you would put
78 + // images into the `src` and `import` them in code to get their paths.
79 + PUBLIC_URL: publicUrl,
80 + }
81 + );
82 + // Stringify all values so we can feed into Webpack DefinePlugin
83 + const stringified = {
84 + 'process.env': Object.keys(raw).reduce((env, key) => {
85 + env[key] = JSON.stringify(raw[key]);
86 + return env;
87 + }, {}),
88 + };
89 +
90 + return {raw, stringified};
91 +}
92 +
93 +module.exports = getClientEnvironment;
fixtures/flight/config/jest/cssTransform.js new
+14
@@ -0,0 +1,14 @@
1 +'use strict';
2 +
3 +// This is a custom Jest transformer turning style imports into empty objects.
4 +// http://facebook.github.io/jest/docs/en/webpack.html
5 +
6 +module.exports = {
7 + process() {
8 + return 'module.exports = {};';
9 + },
10 + getCacheKey() {
11 + // The output is always the same.
12 + return 'cssTransform';
13 + },
14 +};
fixtures/flight/config/jest/fileTransform.js new
+40
@@ -0,0 +1,40 @@
1 +'use strict';
2 +
3 +const path = require('path');
4 +const camelcase = require('camelcase');
5 +
6 +// This is a custom Jest transformer turning file imports into filenames.
7 +// http://facebook.github.io/jest/docs/en/webpack.html
8 +
9 +module.exports = {
10 + process(src, filename) {
11 + const assetFilename = JSON.stringify(path.basename(filename));
12 +
13 + if (filename.match(/\.svg$/)) {
14 + // Based on how SVGR generates a component name:
15 + // https://github.com/smooth-code/svgr/blob/01b194cf967347d43d4cbe6b434404731b87cf27/packages/core/src/state.js#L6
16 + const pascalCaseFilename = camelcase(path.parse(filename).name, {
17 + pascalCase: true,
18 + });
19 + const componentName = `Svg${pascalCaseFilename}`;
20 + return `const React = require('react');
21 + module.exports = {
22 + __esModule: true,
23 + default: ${assetFilename},
24 + ReactComponent: React.forwardRef(function ${componentName}(props, ref) {
25 + return {
26 + $$typeof: Symbol.for('react.element'),
27 + type: 'svg',
28 + ref: ref,
29 + key: null,
30 + props: Object.assign({}, props, {
31 + children: ${assetFilename}
32 + })
33 + };
34 + }),
35 + };`;
36 + }
37 +
38 + return `module.exports = ${assetFilename};`;
39 + },
40 +};
fixtures/flight/config/modules.js new
+141
@@ -0,0 +1,141 @@
1 +'use strict';
2 +
3 +const fs = require('fs');
4 +const path = require('path');
5 +const paths = require('./paths');
6 +const chalk = require('react-dev-utils/chalk');
7 +const resolve = require('resolve');
8 +
9 +/**
10 + * Get additional module paths based on the baseUrl of a compilerOptions object.
11 + *
12 + * @param {Object} options
13 + */
14 +function getAdditionalModulePaths(options = {}) {
15 + const baseUrl = options.baseUrl;
16 +
17 + // We need to explicitly check for null and undefined (and not a falsy value) because
18 + // TypeScript treats an empty string as `.`.
19 + if (baseUrl == null) {
20 + // If there's no baseUrl set we respect NODE_PATH
21 + // Note that NODE_PATH is deprecated and will be removed
22 + // in the next major release of create-react-app.
23 +
24 + const nodePath = process.env.NODE_PATH || '';
25 + return nodePath.split(path.delimiter).filter(Boolean);
26 + }
27 +
28 + const baseUrlResolved = path.resolve(paths.appPath, baseUrl);
29 +
30 + // We don't need to do anything if `baseUrl` is set to `node_modules`. This is
31 + // the default behavior.
32 + if (path.relative(paths.appNodeModules, baseUrlResolved) === '') {
33 + return null;
34 + }
35 +
36 + // Allow the user set the `baseUrl` to `appSrc`.
37 + if (path.relative(paths.appSrc, baseUrlResolved) === '') {
38 + return [paths.appSrc];
39 + }
40 +
41 + // If the path is equal to the root directory we ignore it here.
42 + // We don't want to allow importing from the root directly as source files are
43 + // not transpiled outside of `src`. We do allow importing them with the
44 + // absolute path (e.g. `src/Components/Button.js`) but we set that up with
45 + // an alias.
46 + if (path.relative(paths.appPath, baseUrlResolved) === '') {
47 + return null;
48 + }
49 +
50 + // Otherwise, throw an error.
51 + throw new Error(
52 + chalk.red.bold(
53 + "Your project's `baseUrl` can only be set to `src` or `node_modules`." +
54 + ' Create React App does not support other values at this time.'
55 + )
56 + );
57 +}
58 +
59 +/**
60 + * Get webpack aliases based on the baseUrl of a compilerOptions object.
61 + *
62 + * @param {*} options
63 + */
64 +function getWebpackAliases(options = {}) {
65 + const baseUrl = options.baseUrl;
66 +
67 + if (!baseUrl) {
68 + return {};
69 + }
70 +
71 + const baseUrlResolved = path.resolve(paths.appPath, baseUrl);
72 +
73 + if (path.relative(paths.appPath, baseUrlResolved) === '') {
74 + return {
75 + src: paths.appSrc,
76 + };
77 + }
78 +}
79 +
80 +/**
81 + * Get jest aliases based on the baseUrl of a compilerOptions object.
82 + *
83 + * @param {*} options
84 + */
85 +function getJestAliases(options = {}) {
86 + const baseUrl = options.baseUrl;
87 +
88 + if (!baseUrl) {
89 + return {};
90 + }
91 +
92 + const baseUrlResolved = path.resolve(paths.appPath, baseUrl);
93 +
94 + if (path.relative(paths.appPath, baseUrlResolved) === '') {
95 + return {
96 + 'src/(.*)$': '<rootDir>/src/$1',
97 + };
98 + }
99 +}
100 +
101 +function getModules() {
102 + // Check if TypeScript is setup
103 + const hasTsConfig = fs.existsSync(paths.appTsConfig);
104 + const hasJsConfig = fs.existsSync(paths.appJsConfig);
105 +
106 + if (hasTsConfig && hasJsConfig) {
107 + throw new Error(
108 + 'You have both a tsconfig.json and a jsconfig.json. If you are using TypeScript please remove your jsconfig.json file.'
109 + );
110 + }
111 +
112 + let config;
113 +
114 + // If there's a tsconfig.json we assume it's a
115 + // TypeScript project and set up the config
116 + // based on tsconfig.json
117 + if (hasTsConfig) {
118 + const ts = require(resolve.sync('typescript', {
119 + basedir: paths.appNodeModules,
120 + }));
121 + config = ts.readConfigFile(paths.appTsConfig, ts.sys.readFile).config;
122 + // Otherwise we'll check if there is jsconfig.json
123 + // for non TS projects.
124 + } else if (hasJsConfig) {
125 + config = require(paths.appJsConfig);
126 + }
127 +
128 + config = config || {};
129 + const options = config.compilerOptions || {};
130 +
131 + const additionalModulePaths = getAdditionalModulePaths(options);
132 +
133 + return {
134 + additionalModulePaths: additionalModulePaths,
135 + webpackAliases: getWebpackAliases(options),
136 + jestAliases: getJestAliases(options),
137 + hasTsConfig,
138 + };
139 +}
140 +
141 +module.exports = getModules();
fixtures/flight/config/paths.js new
+88
@@ -0,0 +1,88 @@
1 +'use strict';
2 +
3 +const path = require('path');
4 +const fs = require('fs');
5 +const url = require('url');
6 +
7 +// Make sure any symlinks in the project folder are resolved:
8 +// https://github.com/facebook/create-react-app/issues/637
9 +const appDirectory = fs.realpathSync(process.cwd());
10 +const resolveApp = relativePath => path.resolve(appDirectory, relativePath);
11 +
12 +const envPublicUrl = process.env.PUBLIC_URL;
13 +
14 +function ensureSlash(inputPath, needsSlash) {
15 + const hasSlash = inputPath.endsWith('/');
16 + if (hasSlash && !needsSlash) {
17 + return inputPath.substr(0, inputPath.length - 1);
18 + } else if (!hasSlash && needsSlash) {
19 + return `${inputPath}/`;
20 + } else {
21 + return inputPath;
22 + }
23 +}
24 +
25 +const getPublicUrl = appPackageJson =>
26 + envPublicUrl || require(appPackageJson).homepage;
27 +
28 +// We use `PUBLIC_URL` environment variable or "homepage" field to infer
29 +// "public path" at which the app is served.
30 +// Webpack needs to know it to put the right <script> hrefs into HTML even in
31 +// single-page apps that may serve index.html for nested URLs like /todos/42.
32 +// We can't use a relative path in HTML because we don't want to load something
33 +// like /todos/42/static/js/bundle.7289d.js. We have to know the root.
34 +function getServedPath(appPackageJson) {
35 + const publicUrl = getPublicUrl(appPackageJson);
36 + const servedUrl =
37 + envPublicUrl || (publicUrl ? url.parse(publicUrl).pathname : '/');
38 + return ensureSlash(servedUrl, true);
39 +}
40 +
41 +const moduleFileExtensions = [
42 + 'web.mjs',
43 + 'mjs',
44 + 'web.js',
45 + 'js',
46 + 'web.ts',
47 + 'ts',
48 + 'web.tsx',
49 + 'tsx',
50 + 'json',
51 + 'web.jsx',
52 + 'jsx',
53 +];
54 +
55 +// Resolve file paths in the same order as webpack
56 +const resolveModule = (resolveFn, filePath) => {
57 + const extension = moduleFileExtensions.find(extension =>
58 + fs.existsSync(resolveFn(`${filePath}.${extension}`))
59 + );
60 +
61 + if (extension) {
62 + return resolveFn(`${filePath}.${extension}`);
63 + }
64 +
65 + return resolveFn(`${filePath}.js`);
66 +};
67 +
68 +// config after eject: we're in ./config/
69 +module.exports = {
70 + dotenv: resolveApp('.env'),
71 + appPath: resolveApp('.'),
72 + appBuild: resolveApp('build'),
73 + appPublic: resolveApp('public'),
74 + appHtml: resolveApp('public/index.html'),
75 + appIndexJs: resolveModule(resolveApp, 'src/index'),
76 + appPackageJson: resolveApp('package.json'),
77 + appSrc: resolveApp('src'),
78 + appTsConfig: resolveApp('tsconfig.json'),
79 + appJsConfig: resolveApp('jsconfig.json'),
80 + yarnLockFile: resolveApp('yarn.lock'),
81 + testsSetup: resolveModule(resolveApp, 'src/setupTests'),
82 + proxySetup: resolveApp('src/setupProxy.js'),
83 + appNodeModules: resolveApp('node_modules'),
84 + publicUrl: getPublicUrl(resolveApp('package.json')),
85 + servedPath: getServedPath(resolveApp('package.json')),
86 +};
87 +
88 +module.exports.moduleFileExtensions = moduleFileExtensions;
fixtures/flight/config/pnpTs.js new
+35
@@ -0,0 +1,35 @@
1 +'use strict';
2 +
3 +const {resolveModuleName} = require('ts-pnp');
4 +
5 +exports.resolveModuleName = (
6 + typescript,
7 + moduleName,
8 + containingFile,
9 + compilerOptions,
10 + resolutionHost
11 +) => {
12 + return resolveModuleName(
13 + moduleName,
14 + containingFile,
15 + compilerOptions,
16 + resolutionHost,
17 + typescript.resolveModuleName
18 + );
19 +};
20 +
21 +exports.resolveTypeReferenceDirective = (
22 + typescript,
23 + moduleName,
24 + containingFile,
25 + compilerOptions,
26 + resolutionHost
27 +) => {
28 + return resolveModuleName(
29 + moduleName,
30 + containingFile,
31 + compilerOptions,
32 + resolutionHost,
33 + typescript.resolveTypeReferenceDirective
34 + );
35 +};
fixtures/flight/config/webpack.config.js new
+686
@@ -0,0 +1,686 @@
1 +'use strict';
2 +
3 +// Fork Start
4 +const ReactFlightWebpackPlugin = require('react-flight-dom-webpack/plugin');
5 +// Fork End
6 +
7 +const fs = require('fs');
8 +const isWsl = require('is-wsl');
9 +const path = require('path');
10 +const webpack = require('webpack');
11 +const resolve = require('resolve');
12 +const PnpWebpackPlugin = require('pnp-webpack-plugin');
13 +const HtmlWebpackPlugin = require('html-webpack-plugin');
14 +const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
15 +const InlineChunkHtmlPlugin = require('react-dev-utils/InlineChunkHtmlPlugin');
16 +const TerserPlugin = require('terser-webpack-plugin');
17 +const MiniCssExtractPlugin = require('mini-css-extract-plugin');
18 +const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
19 +const safePostCssParser = require('postcss-safe-parser');
20 +const ManifestPlugin = require('webpack-manifest-plugin');
21 +const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
22 +const WorkboxWebpackPlugin = require('workbox-webpack-plugin');
23 +const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
24 +const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
25 +const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent');
26 +const paths = require('./paths');
27 +const modules = require('./modules');
28 +const getClientEnvironment = require('./env');
29 +const ModuleNotFoundPlugin = require('react-dev-utils/ModuleNotFoundPlugin');
30 +const ForkTsCheckerWebpackPlugin = require('react-dev-utils/ForkTsCheckerWebpackPlugin');
31 +const typescriptFormatter = require('react-dev-utils/typescriptFormatter');
32 +const eslint = require('eslint');
33 +
34 +const postcssNormalize = require('postcss-normalize');
35 +
36 +const appPackageJson = require(paths.appPackageJson);
37 +
38 +// Source maps are resource heavy and can cause out of memory issue for large source files.
39 +const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';
40 +// Some apps do not need the benefits of saving a web request, so not inlining the chunk
41 +// makes for a smoother build process.
42 +const shouldInlineRuntimeChunk = process.env.INLINE_RUNTIME_CHUNK !== 'false';
43 +
44 +const imageInlineSizeLimit = parseInt(
45 + process.env.IMAGE_INLINE_SIZE_LIMIT || '10000'
46 +);
47 +
48 +// Check if TypeScript is setup
49 +const useTypeScript = fs.existsSync(paths.appTsConfig);
50 +
51 +// style files regexes
52 +const cssRegex = /\.css$/;
53 +const cssModuleRegex = /\.module\.css$/;
54 +const sassRegex = /\.(scss|sass)$/;
55 +const sassModuleRegex = /\.module\.(scss|sass)$/;
56 +
57 +// This is the production and development configuration.
58 +// It is focused on developer experience, fast rebuilds, and a minimal bundle.
59 +module.exports = function(webpackEnv) {
60 + const isEnvDevelopment = webpackEnv === 'development';
61 + const isEnvProduction = webpackEnv === 'production';
62 +
63 + // Variable used for enabling profiling in Production
64 + // passed into alias object. Uses a flag if passed into the build command
65 + const isEnvProductionProfile =
66 + isEnvProduction && process.argv.includes('--profile');
67 +
68 + // Webpack uses `publicPath` to determine where the app is being served from.
69 + // It requires a trailing slash, or the file assets will get an incorrect path.
70 + // In development, we always serve from the root. This makes config easier.
71 + const publicPath = isEnvProduction
72 + ? paths.servedPath
73 + : isEnvDevelopment && '/';
74 + // Some apps do not use client-side routing with pushState.
75 + // For these, "homepage" can be set to "." to enable relative asset paths.
76 + const shouldUseRelativeAssetPaths = publicPath === './';
77 +
78 + // `publicUrl` is just like `publicPath`, but we will provide it to our app
79 + // as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
80 + // Omit trailing slash as %PUBLIC_URL%/xyz looks better than %PUBLIC_URL%xyz.
81 + const publicUrl = isEnvProduction
82 + ? publicPath.slice(0, -1)
83 + : isEnvDevelopment && '';
84 + // Get environment variables to inject into our app.
85 + const env = getClientEnvironment(publicUrl);
86 +
87 + // common function to get style loaders
88 + const getStyleLoaders = (cssOptions, preProcessor) => {
89 + const loaders = [
90 + isEnvDevelopment && require.resolve('style-loader'),
91 + isEnvProduction && {
92 + loader: MiniCssExtractPlugin.loader,
93 + options: shouldUseRelativeAssetPaths ? {publicPath: '../../'} : {},
94 + },
95 + {
96 + loader: require.resolve('css-loader'),
97 + options: cssOptions,
98 + },
99 + {
100 + // Options for PostCSS as we reference these options twice
101 + // Adds vendor prefixing based on your specified browser support in
102 + // package.json
103 + loader: require.resolve('postcss-loader'),
104 + options: {
105 + // Necessary for external CSS imports to work
106 + // https://github.com/facebook/create-react-app/issues/2677
107 + ident: 'postcss',
108 + plugins: () => [
109 + require('postcss-flexbugs-fixes'),
110 + require('postcss-preset-env')({
111 + autoprefixer: {
112 + flexbox: 'no-2009',
113 + },
114 + stage: 3,
115 + }),
116 + // Adds PostCSS Normalize as the reset css with default options,
117 + // so that it honors browserslist config in package.json
118 + // which in turn let's users customize the target behavior as per their needs.
119 + postcssNormalize(),
120 + ],
121 + sourceMap: isEnvProduction && shouldUseSourceMap,
122 + },
123 + },
124 + ].filter(Boolean);
125 + if (preProcessor) {
126 + loaders.push(
127 + {
128 + loader: require.resolve('resolve-url-loader'),
129 + options: {
130 + sourceMap: isEnvProduction && shouldUseSourceMap,
131 + },
132 + },
133 + {
134 + loader: require.resolve(preProcessor),
135 + options: {
136 + sourceMap: true,
137 + },
138 + }
139 + );
140 + }
141 + return loaders;
142 + };
143 +
144 + return {
145 + mode: isEnvProduction ? 'production' : isEnvDevelopment && 'development',
146 + // Stop compilation early in production
147 + bail: isEnvProduction,
148 + devtool: isEnvProduction
149 + ? shouldUseSourceMap
150 + ? 'source-map'
151 + : false
152 + : isEnvDevelopment && 'cheap-module-source-map',
153 + // These are the "entry points" to our application.
154 + // This means they will be the "root" imports that are included in JS bundle.
155 + entry: [
156 + // Include an alternative client for WebpackDevServer. A client's job is to
157 + // connect to WebpackDevServer by a socket and get notified about changes.
158 + // When you save a file, the client will either apply hot updates (in case
159 + // of CSS changes), or refresh the page (in case of JS changes). When you
160 + // make a syntax error, this client will display a syntax error overlay.
161 + // Note: instead of the default WebpackDevServer client, we use a custom one
162 + // to bring better experience for Create React App users. You can replace
163 + // the line below with these two lines if you prefer the stock client:
164 + // require.resolve('webpack-dev-server/client') + '?/',
165 + // require.resolve('webpack/hot/dev-server'),
166 + isEnvDevelopment &&
167 + require.resolve('react-dev-utils/webpackHotDevClient'),
168 + // Finally, this is your app's code:
169 + paths.appIndexJs,
170 + // We include the app code last so that if there is a runtime error during
171 + // initialization, it doesn't blow up the WebpackDevServer client, and
172 + // changing JS code would still trigger a refresh.
173 + ].filter(Boolean),
174 + output: {
175 + // The build folder.
176 + path: isEnvProduction ? paths.appBuild : undefined,
177 + // Add /* filename */ comments to generated require()s in the output.
178 + pathinfo: isEnvDevelopment,
179 + // There will be one main bundle, and one file per asynchronous chunk.
180 + // In development, it does not produce real files.
181 + filename: isEnvProduction
182 + ? 'static/js/[name].[contenthash:8].js'
183 + : isEnvDevelopment && 'static/js/bundle.js',
184 + // TODO: remove this when upgrading to webpack 5
185 + futureEmitAssets: true,
186 + // There are also additional JS chunk files if you use code splitting.
187 + chunkFilename: isEnvProduction
188 + ? 'static/js/[name].[contenthash:8].chunk.js'
189 + : isEnvDevelopment && 'static/js/[name].chunk.js',
190 + // We inferred the "public path" (such as / or /my-project) from homepage.
191 + // We use "/" in development.
192 + publicPath: publicPath,
193 + // Point sourcemap entries to original disk location (format as URL on Windows)
194 + devtoolModuleFilenameTemplate: isEnvProduction
195 + ? info =>
196 + path
197 + .relative(paths.appSrc, info.absoluteResourcePath)
198 + .replace(/\\/g, '/')
199 + : isEnvDevelopment &&
200 + (info => path.resolve(info.absoluteResourcePath).replace(/\\/g, '/')),
201 + // Prevents conflicts when multiple Webpack runtimes (from different apps)
202 + // are used on the same page.
203 + jsonpFunction: `webpackJsonp${appPackageJson.name}`,
204 + // this defaults to 'window', but by setting it to 'this' then
205 + // module chunks which are built will work in web workers as well.
206 + globalObject: 'this',
207 + },
208 + optimization: {
209 + minimize: isEnvProduction,
210 + minimizer: [
211 + // This is only used in production mode
212 + new TerserPlugin({
213 + terserOptions: {
214 + parse: {
215 + // We want terser to parse ecma 8 code. However, we don't want it
216 + // to apply any minification steps that turns valid ecma 5 code
217 + // into invalid ecma 5 code. This is why the 'compress' and 'output'
218 + // sections only apply transformations that are ecma 5 safe
219 + // https://github.com/facebook/create-react-app/pull/4234
220 + ecma: 8,
221 + },
222 + compress: {
223 + ecma: 5,
224 + warnings: false,
225 + // Disabled because of an issue with Uglify breaking seemingly valid code:
226 + // https://github.com/facebook/create-react-app/issues/2376
227 + // Pending further investigation:
228 + // https://github.com/mishoo/UglifyJS2/issues/2011
229 + comparisons: false,
230 + // Disabled because of an issue with Terser breaking valid code:
231 + // https://github.com/facebook/create-react-app/issues/5250
232 + // Pending further investigation:
233 + // https://github.com/terser-js/terser/issues/120
234 + inline: 2,
235 + },
236 + mangle: {
237 + safari10: true,
238 + },
239 + // Added for profiling in devtools
240 + keep_classnames: isEnvProductionProfile,
241 + keep_fnames: isEnvProductionProfile,
242 + output: {
243 + ecma: 5,
244 + comments: false,
245 + // Turned on because emoji and regex is not minified properly using default
246 + // https://github.com/facebook/create-react-app/issues/2488
247 + ascii_only: true,
248 + },
249 + },
250 + // Use multi-process parallel running to improve the build speed
251 + // Default number of concurrent runs: os.cpus().length - 1
252 + // Disabled on WSL (Windows Subsystem for Linux) due to an issue with Terser
253 + // https://github.com/webpack-contrib/terser-webpack-plugin/issues/21
254 + parallel: !isWsl,
255 + // Enable file caching
256 + cache: true,
257 + sourceMap: shouldUseSourceMap,
258 + }),
259 + // This is only used in production mode
260 + new OptimizeCSSAssetsPlugin({
261 + cssProcessorOptions: {
262 + parser: safePostCssParser,
263 + map: shouldUseSourceMap
264 + ? {
265 + // `inline: false` forces the sourcemap to be output into a
266 + // separate file
267 + inline: false,
268 + // `annotation: true` appends the sourceMappingURL to the end of
269 + // the css file, helping the browser find the sourcemap
270 + annotation: true,
271 + }
272 + : false,
273 + },
274 + }),
275 + ],
276 + // Automatically split vendor and commons
277 + // https://twitter.com/wSokra/status/969633336732905474
278 + // https://medium.com/webpack/webpack-4-code-splitting-chunk-graph-and-the-splitchunks-optimization-be739a861366
279 + splitChunks: {
280 + chunks: 'all',
281 + name: false,
282 + },
283 + // Keep the runtime chunk separated to enable long term caching
284 + // https://twitter.com/wSokra/status/969679223278505985
285 + // https://github.com/facebook/create-react-app/issues/5358
286 + runtimeChunk: {
287 + name: entrypoint => `runtime-${entrypoint.name}`,
288 + },
289 + },
290 + resolve: {
291 + // This allows you to set a fallback for where Webpack should look for modules.
292 + // We placed these paths second because we want `node_modules` to "win"
293 + // if there are any conflicts. This matches Node resolution mechanism.
294 + // https://github.com/facebook/create-react-app/issues/253
295 + modules: ['node_modules', paths.appNodeModules].concat(
296 + modules.additionalModulePaths || []
297 + ),
298 + // These are the reasonable defaults supported by the Node ecosystem.
299 + // We also include JSX as a common component filename extension to support
300 + // some tools, although we do not recommend using it, see:
301 + // https://github.com/facebook/create-react-app/issues/290
302 + // `web` extension prefixes have been added for better support
303 + // for React Native Web.
304 + extensions: paths.moduleFileExtensions
305 + .map(ext => `.${ext}`)
306 + .filter(ext => useTypeScript || !ext.includes('ts')),
307 + alias: {
308 + // Support React Native Web
309 + // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
310 + 'react-native': 'react-native-web',
311 + // Allows for better profiling with ReactDevTools
312 + ...(isEnvProductionProfile && {
313 + 'react-dom$': 'react-dom/profiling',
314 + 'scheduler/tracing': 'scheduler/tracing-profiling',
315 + }),
316 + ...(modules.webpackAliases || {}),
317 + },
318 + plugins: [
319 + // Adds support for installing with Plug'n'Play, leading to faster installs and adding
320 + // guards against forgotten dependencies and such.
321 + PnpWebpackPlugin,
322 + // Prevents users from importing files from outside of src/ (or node_modules/).
323 + // This often causes confusion because we only process files within src/ with babel.
324 + // To fix this, we prevent you from importing files out of src/ -- if you'd like to,
325 + // please link the files into your node_modules/ and let module-resolution kick in.
326 + // Make sure your source files are compiled, as they will not be processed in any way.
327 + new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
328 + ],
329 + },
330 + resolveLoader: {
331 + plugins: [
332 + // Also related to Plug'n'Play, but this time it tells Webpack to load its loaders
333 + // from the current package.
334 + PnpWebpackPlugin.moduleLoader(module),
335 + ],
336 + },
337 + module: {
338 + strictExportPresence: true,
339 + rules: [
340 + // Disable require.ensure as it's not a standard language feature.
341 + {parser: {requireEnsure: false}},
342 +
343 + // First, run the linter.
344 + // It's important to do this before Babel processes the JS.
345 + {
346 + test: /\.(js|mjs|jsx|ts|tsx)$/,
347 + enforce: 'pre',
348 + use: [
349 + {
350 + options: {
351 + cache: true,
352 + formatter: require.resolve('react-dev-utils/eslintFormatter'),
353 + eslintPath: require.resolve('eslint'),
354 + resolvePluginsRelativeTo: __dirname,
355 + },
356 + loader: require.resolve('eslint-loader'),
357 + },
358 + ],
359 + include: paths.appSrc,
360 + },
361 + {
362 + // "oneOf" will traverse all following loaders until one will
363 + // match the requirements. When no loader matches it will fall
364 + // back to the "file" loader at the end of the loader list.
365 + oneOf: [
366 + // "url" loader works like "file" loader except that it embeds assets
367 + // smaller than specified limit in bytes as data URLs to avoid requests.
368 + // A missing `test` is equivalent to a match.
369 + {
370 + test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
371 + loader: require.resolve('url-loader'),
372 + options: {
373 + limit: imageInlineSizeLimit,
374 + name: 'static/media/[name].[hash:8].[ext]',
375 + },
376 + },
377 + // Process application JS with Babel.
378 + // The preset includes JSX, Flow, TypeScript, and some ESnext features.
379 + {
380 + test: /\.(js|mjs|jsx|ts|tsx)$/,
381 + include: paths.appSrc,
382 + loader: require.resolve('babel-loader'),
383 + options: {
384 + customize: require.resolve(
385 + 'babel-preset-react-app/webpack-overrides'
386 + ),
387 +
388 + plugins: [
389 + [
390 + require.resolve('babel-plugin-named-asset-import'),
391 + {
392 + loaderMap: {
393 + svg: {
394 + ReactComponent:
395 + '@svgr/webpack?-svgo,+titleProp,+ref![path]',
396 + },
397 + },
398 + },
399 + ],
400 + ],
401 + // This is a feature of `babel-loader` for webpack (not Babel itself).
402 + // It enables caching results in ./node_modules/.cache/babel-loader/
403 + // directory for faster rebuilds.
404 + cacheDirectory: true,
405 + // See #6846 for context on why cacheCompression is disabled
406 + cacheCompression: false,
407 + compact: isEnvProduction,
408 + },
409 + },
410 + // Process any JS outside of the app with Babel.
411 + // Unlike the application JS, we only compile the standard ES features.
412 + {
413 + test: /\.(js|mjs)$/,
414 + exclude: /@babel(?:\/|\\{1,2})runtime/,
415 + loader: require.resolve('babel-loader'),
416 + options: {
417 + babelrc: false,
418 + configFile: false,
419 + compact: false,
420 + presets: [
421 + [
422 + require.resolve('babel-preset-react-app/dependencies'),
423 + {helpers: true},
424 + ],
425 + ],
426 + cacheDirectory: true,
427 + // See #6846 for context on why cacheCompression is disabled
428 + cacheCompression: false,
429 +
430 + // If an error happens in a package, it's possible to be
431 + // because it was compiled. Thus, we don't want the browser
432 + // debugger to show the original code. Instead, the code
433 + // being evaluated would be much more helpful.
434 + sourceMaps: false,
435 + },
436 + },
437 + // "postcss" loader applies autoprefixer to our CSS.
438 + // "css" loader resolves paths in CSS and adds assets as dependencies.
439 + // "style" loader turns CSS into JS modules that inject <style> tags.
440 + // In production, we use MiniCSSExtractPlugin to extract that CSS
441 + // to a file, but in development "style" loader enables hot editing
442 + // of CSS.
443 + // By default we support CSS Modules with the extension .module.css
444 + {
445 + test: cssRegex,
446 + exclude: cssModuleRegex,
447 + use: getStyleLoaders({
448 + importLoaders: 1,
449 + sourceMap: isEnvProduction && shouldUseSourceMap,
450 + }),
451 + // Don't consider CSS imports dead code even if the
452 + // containing package claims to have no side effects.
453 + // Remove this when webpack adds a warning or an error for this.
454 + // See https://github.com/webpack/webpack/issues/6571
455 + sideEffects: true,
456 + },
457 + // Adds support for CSS Modules (https://github.com/css-modules/css-modules)
458 + // using the extension .module.css
459 + {
460 + test: cssModuleRegex,
461 + use: getStyleLoaders({
462 + importLoaders: 1,
463 + sourceMap: isEnvProduction && shouldUseSourceMap,
464 + modules: true,
465 + getLocalIdent: getCSSModuleLocalIdent,
466 + }),
467 + },
468 + // Opt-in support for SASS (using .scss or .sass extensions).
469 + // By default we support SASS Modules with the
470 + // extensions .module.scss or .module.sass
471 + {
472 + test: sassRegex,
473 + exclude: sassModuleRegex,
474 + use: getStyleLoaders(
475 + {
476 + importLoaders: 2,
477 + sourceMap: isEnvProduction && shouldUseSourceMap,
478 + },
479 + 'sass-loader'
480 + ),
481 + // Don't consider CSS imports dead code even if the
482 + // containing package claims to have no side effects.
483 + // Remove this when webpack adds a warning or an error for this.
484 + // See https://github.com/webpack/webpack/issues/6571
485 + sideEffects: true,
486 + },
487 + // Adds support for CSS Modules, but using SASS
488 + // using the extension .module.scss or .module.sass
489 + {
490 + test: sassModuleRegex,
491 + use: getStyleLoaders(
492 + {
493 + importLoaders: 2,
494 + sourceMap: isEnvProduction && shouldUseSourceMap,
495 + modules: true,
496 + getLocalIdent: getCSSModuleLocalIdent,
497 + },
498 + 'sass-loader'
499 + ),
500 + },
501 + // "file" loader makes sure those assets get served by WebpackDevServer.
502 + // When you `import` an asset, you get its (virtual) filename.
503 + // In production, they would get copied to the `build` folder.
504 + // This loader doesn't use a "test" so it will catch all modules
505 + // that fall through the other loaders.
506 + {
507 + loader: require.resolve('file-loader'),
508 + // Exclude `js` files to keep "css" loader working as it injects
509 + // its runtime that would otherwise be processed through "file" loader.
510 + // Also exclude `html` and `json` extensions so they get processed
511 + // by webpacks internal loaders.
512 + exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/],
513 + options: {
514 + name: 'static/media/[name].[hash:8].[ext]',
515 + },
516 + },
517 + // ** STOP ** Are you adding a new loader?
518 + // Make sure to add the new loader(s) before the "file" loader.
519 + ],
520 + },
521 + ],
522 + },
523 + plugins: [
524 + // Generates an `index.html` file with the <script> injected.
525 + new HtmlWebpackPlugin(
526 + Object.assign(
527 + {},
528 + {
529 + inject: true,
530 + template: paths.appHtml,
531 + },
532 + isEnvProduction
533 + ? {
534 + minify: {
535 + removeComments: true,
536 + collapseWhitespace: true,
537 + removeRedundantAttributes: true,
538 + useShortDoctype: true,
539 + removeEmptyAttributes: true,
540 + removeStyleLinkTypeAttributes: true,
541 + keepClosingSlash: true,
542 + minifyJS: true,
543 + minifyCSS: true,
544 + minifyURLs: true,
545 + },
546 + }
547 + : undefined
548 + )
549 + ),
550 + // Inlines the webpack runtime script. This script is too small to warrant
551 + // a network request.
552 + // https://github.com/facebook/create-react-app/issues/5358
553 + isEnvProduction &&
554 + shouldInlineRuntimeChunk &&
555 + new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/runtime-.+[.]js/]),
556 + // Makes some environment variables available in index.html.
557 + // The public URL is available as %PUBLIC_URL% in index.html, e.g.:
558 + // <link rel="icon" href="%PUBLIC_URL%/favicon.ico">
559 + // In production, it will be an empty string unless you specify "homepage"
560 + // in `package.json`, in which case it will be the pathname of that URL.
561 + // In development, this will be an empty string.
562 + new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw),
563 + // This gives some necessary context to module not found errors, such as
564 + // the requesting resource.
565 + new ModuleNotFoundPlugin(paths.appPath),
566 + // Makes some environment variables available to the JS code, for example:
567 + // if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`.
568 + // It is absolutely essential that NODE_ENV is set to production
569 + // during a production build.
570 + // Otherwise React will be compiled in the very slow development mode.
571 + new webpack.DefinePlugin(env.stringified),
572 + // This is necessary to emit hot updates (currently CSS only):
573 + isEnvDevelopment && new webpack.HotModuleReplacementPlugin(),
574 + // Watcher doesn't work well if you mistype casing in a path so we use
575 + // a plugin that prints an error when you attempt to do this.
576 + // See https://github.com/facebook/create-react-app/issues/240
577 + isEnvDevelopment && new CaseSensitivePathsPlugin(),
578 + // If you require a missing module and then `npm install` it, you still have
579 + // to restart the development server for Webpack to discover it. This plugin
580 + // makes the discovery automatic so you don't have to restart.
581 + // See https://github.com/facebook/create-react-app/issues/186
582 + isEnvDevelopment &&
583 + new WatchMissingNodeModulesPlugin(paths.appNodeModules),
584 + isEnvProduction &&
585 + new MiniCssExtractPlugin({
586 + // Options similar to the same options in webpackOptions.output
587 + // both options are optional
588 + filename: 'static/css/[name].[contenthash:8].css',
589 + chunkFilename: 'static/css/[name].[contenthash:8].chunk.css',
590 + }),
591 + // Generate an asset manifest file with the following content:
592 + // - "files" key: Mapping of all asset filenames to their corresponding
593 + // output file so that tools can pick it up without having to parse
594 + // `index.html`
595 + // - "entrypoints" key: Array of files which are included in `index.html`,
596 + // can be used to reconstruct the HTML if necessary
597 + new ManifestPlugin({
598 + fileName: 'asset-manifest.json',
599 + publicPath: publicPath,
600 + generate: (seed, files, entrypoints) => {
601 + const manifestFiles = files.reduce((manifest, file) => {
602 + manifest[file.name] = file.path;
603 + return manifest;
604 + }, seed);
605 + const entrypointFiles = entrypoints.main.filter(
606 + fileName => !fileName.endsWith('.map')
607 + );
608 +
609 + return {
610 + files: manifestFiles,
611 + entrypoints: entrypointFiles,
612 + };
613 + },
614 + }),
615 + // Moment.js is an extremely popular library that bundles large locale files
616 + // by default due to how Webpack interprets its code. This is a practical
617 + // solution that requires the user to opt into importing specific locales.
618 + // https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
619 + // You can remove this if you don't use Moment.js:
620 + new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
621 + // Generate a service worker script that will precache, and keep up to date,
622 + // the HTML & assets that are part of the Webpack build.
623 + isEnvProduction &&
624 + new WorkboxWebpackPlugin.GenerateSW({
625 + clientsClaim: true,
626 + exclude: [/\.map$/, /asset-manifest\.json$/],
627 + importWorkboxFrom: 'cdn',
628 + navigateFallback: publicUrl + '/index.html',
629 + navigateFallbackBlacklist: [
630 + // Exclude URLs starting with /_, as they're likely an API call
631 + new RegExp('^/_'),
632 + // Exclude any URLs whose last part seems to be a file extension
633 + // as they're likely a resource and not a SPA route.
634 + // URLs containing a "?" character won't be blacklisted as they're likely
635 + // a route with query params (e.g. auth callbacks).
636 + new RegExp('/[^/?]+\\.[^/]+$'),
637 + ],
638 + }),
639 + // TypeScript type checking
640 + useTypeScript &&
641 + new ForkTsCheckerWebpackPlugin({
642 + typescript: resolve.sync('typescript', {
643 + basedir: paths.appNodeModules,
644 + }),
645 + async: isEnvDevelopment,
646 + useTypescriptIncrementalApi: true,
647 + checkSyntacticErrors: true,
648 + resolveModuleNameModule: process.versions.pnp
649 + ? `${__dirname}/pnpTs.js`
650 + : undefined,
651 + resolveTypeReferenceDirectiveModule: process.versions.pnp
652 + ? `${__dirname}/pnpTs.js`
653 + : undefined,
654 + tsconfig: paths.appTsConfig,
655 + reportFiles: [
656 + '**',
657 + '!**/__tests__/**',
658 + '!**/?(*.)(spec|test).*',
659 + '!**/src/setupProxy.*',
660 + '!**/src/setupTests.*',
661 + ],
662 + silent: true,
663 + // The formatter is invoked directly in WebpackDevServerUtils during development
664 + formatter: isEnvProduction ? typescriptFormatter : undefined,
665 + }),
666 + // Fork Start
667 + new ReactFlightWebpackPlugin({isServer: false}),
668 + // Fork End
669 + ].filter(Boolean),
670 + // Some libraries import Node modules but don't use them in the browser.
671 + // Tell Webpack to provide empty mocks for them so importing them works.
672 + node: {
673 + module: 'empty',
674 + dgram: 'empty',
675 + dns: 'mock',
676 + fs: 'empty',
677 + http2: 'empty',
678 + net: 'empty',
679 + tls: 'empty',
680 + child_process: 'empty',
681 + },
682 + // Turn off performance processing because we utilize
683 + // our own hints via the FileSizeReporter
684 + performance: false,
685 + };
686 +};
fixtures/flight/config/webpackDevServer.config.js new
+104
@@ -0,0 +1,104 @@
1 +'use strict';
2 +
3 +const errorOverlayMiddleware = require('react-dev-utils/errorOverlayMiddleware');
4 +const evalSourceMapMiddleware = require('react-dev-utils/evalSourceMapMiddleware');
5 +const noopServiceWorkerMiddleware = require('react-dev-utils/noopServiceWorkerMiddleware');
6 +const ignoredFiles = require('react-dev-utils/ignoredFiles');
7 +const paths = require('./paths');
8 +const fs = require('fs');
9 +
10 +const protocol = process.env.HTTPS === 'true' ? 'https' : 'http';
11 +const host = process.env.HOST || '0.0.0.0';
12 +
13 +module.exports = function(proxy, allowedHost) {
14 + return {
15 + // WebpackDevServer 2.4.3 introduced a security fix that prevents remote
16 + // websites from potentially accessing local content through DNS rebinding:
17 + // https://github.com/webpack/webpack-dev-server/issues/887
18 + // https://medium.com/webpack/webpack-dev-server-middleware-security-issues-1489d950874a
19 + // However, it made several existing use cases such as development in cloud
20 + // environment or subdomains in development significantly more complicated:
21 + // https://github.com/facebook/create-react-app/issues/2271
22 + // https://github.com/facebook/create-react-app/issues/2233
23 + // While we're investigating better solutions, for now we will take a
24 + // compromise. Since our WDS configuration only serves files in the `public`
25 + // folder we won't consider accessing them a vulnerability. However, if you
26 + // use the `proxy` feature, it gets more dangerous because it can expose
27 + // remote code execution vulnerabilities in backends like Django and Rails.
28 + // So we will disable the host check normally, but enable it if you have
29 + // specified the `proxy` setting. Finally, we let you override it if you
30 + // really know what you're doing with a special environment variable.
31 + disableHostCheck:
32 + !proxy || process.env.DANGEROUSLY_DISABLE_HOST_CHECK === 'true',
33 + // Enable gzip compression of generated files.
34 + compress: true,
35 + // Silence WebpackDevServer's own logs since they're generally not useful.
36 + // It will still show compile warnings and errors with this setting.
37 + clientLogLevel: 'none',
38 + // By default WebpackDevServer serves physical files from current directory
39 + // in addition to all the virtual build products that it serves from memory.
40 + // This is confusing because those files won’t automatically be available in
41 + // production build folder unless we copy them. However, copying the whole
42 + // project directory is dangerous because we may expose sensitive files.
43 + // Instead, we establish a convention that only files in `public` directory
44 + // get served. Our build script will copy `public` into the `build` folder.
45 + // In `index.html`, you can get URL of `public` folder with %PUBLIC_URL%:
46 + // <link rel="icon" href="%PUBLIC_URL%/favicon.ico">
47 + // In JavaScript code, you can access it with `process.env.PUBLIC_URL`.
48 + // Note that we only recommend to use `public` folder as an escape hatch
49 + // for files like `favicon.ico`, `manifest.json`, and libraries that are
50 + // for some reason broken when imported through Webpack. If you just want to
51 + // use an image, put it in `src` and `import` it from JavaScript instead.
52 + contentBase: paths.appPublic,
53 + // By default files from `contentBase` will not trigger a page reload.
54 + watchContentBase: true,
55 + // Enable hot reloading server. It will provide /sockjs-node/ endpoint
56 + // for the WebpackDevServer client so it can learn when the files were
57 + // updated. The WebpackDevServer client is included as an entry point
58 + // in the Webpack development configuration. Note that only changes
59 + // to CSS are currently hot reloaded. JS changes will refresh the browser.
60 + hot: true,
61 + // It is important to tell WebpackDevServer to use the same "root" path
62 + // as we specified in the config. In development, we always serve from /.
63 + publicPath: '/',
64 + // WebpackDevServer is noisy by default so we emit custom message instead
65 + // by listening to the compiler events with `compiler.hooks[...].tap` calls above.
66 + quiet: true,
67 + // Reportedly, this avoids CPU overload on some systems.
68 + // https://github.com/facebook/create-react-app/issues/293
69 + // src/node_modules is not ignored to support absolute imports
70 + // https://github.com/facebook/create-react-app/issues/1065
71 + watchOptions: {
72 + ignored: ignoredFiles(paths.appSrc),
73 + },
74 + // Enable HTTPS if the HTTPS environment variable is set to 'true'
75 + https: protocol === 'https',
76 + host,
77 + overlay: false,
78 + historyApiFallback: {
79 + // Paths with dots should still use the history fallback.
80 + // See https://github.com/facebook/create-react-app/issues/387.
81 + disableDotRule: true,
82 + },
83 + public: allowedHost,
84 + proxy,
85 + before(app, server) {
86 + if (fs.existsSync(paths.proxySetup)) {
87 + // This registers user provided middleware for proxy reasons
88 + require(paths.proxySetup)(app);
89 + }
90 +
91 + // This lets us fetch source contents from webpack for the error overlay
92 + app.use(evalSourceMapMiddleware(server));
93 + // This lets us open files from the runtime error overlay.
94 + app.use(errorOverlayMiddleware());
95 +
96 + // This service worker file is effectively a 'no-op' that will reset any
97 + // previous service worker registered for the same host:port combination.
98 + // We do this in development to avoid hitting the production cache if
99 + // it used the same host and port.
100 + // https://github.com/facebook/create-react-app/issues/2272#issuecomment-302832432
101 + app.use(noopServiceWorkerMiddleware());
102 + },
103 + };
104 +};
fixtures/flight/package.json
+110 -6
@@ -3,21 +3,72 @@
3 "version": "0.1.0",
4 "private": true,
5 "dependencies": {
6 + "@babel/core": "7.6.0",
7 "@babel/register": "^7.7.0",
8 + "@svgr/webpack": "4.3.2",
9 + "@typescript-eslint/eslint-plugin": "^2.2.0",
10 + "@typescript-eslint/parser": "^2.2.0",
11 + "babel-eslint": "10.0.3",
12 + "babel-jest": "^24.9.0",
13 + "babel-loader": "8.0.6",
14 + "babel-plugin-named-asset-import": "^0.3.4",
15 + "babel-preset-react-app": "^9.0.2",
16 + "camelcase": "^5.2.0",
17 + "case-sensitive-paths-webpack-plugin": "2.2.0",
18 "concurrently": "^5.0.0",
19 + "css-loader": "2.1.1",
20 + "dotenv": "6.2.0",
21 + "dotenv-expand": "5.1.0",
22 + "eslint": "^6.1.0",
23 + "eslint-config-react-app": "^5.0.2",
24 + "eslint-loader": "3.0.2",
25 + "eslint-plugin-flowtype": "3.13.0",
26 + "eslint-plugin-import": "2.18.2",
27 + "eslint-plugin-jsx-a11y": "6.2.3",
28 + "eslint-plugin-react": "7.14.3",
29 + "eslint-plugin-react-hooks": "^1.6.1",
30 "express": "^4.17.1",
9 - "react-scripts": "3.2.0"
31 + "file-loader": "3.0.1",
32 + "fs-extra": "7.0.1",
33 + "html-webpack-plugin": "4.0.0-beta.5",
34 + "identity-obj-proxy": "3.0.0",
35 + "is-wsl": "^1.1.0",
36 + "jest": "24.9.0",
37 + "jest-environment-jsdom-fourteen": "0.1.0",
38 + "jest-resolve": "24.9.0",
39 + "jest-watch-typeahead": "0.4.0",
40 + "mini-css-extract-plugin": "0.8.0",
41 + "optimize-css-assets-webpack-plugin": "5.0.3",
42 + "pnp-webpack-plugin": "1.5.0",
43 + "postcss-flexbugs-fixes": "4.1.0",
44 + "postcss-loader": "3.0.0",
45 + "postcss-normalize": "7.0.1",
46 + "postcss-preset-env": "6.7.0",
47 + "postcss-safe-parser": "4.0.1",
48 + "react-app-polyfill": "^1.0.4",
49 + "react-dev-utils": "^9.1.0",
50 + "resolve": "1.12.0",
51 + "resolve-url-loader": "3.1.0",
52 + "sass-loader": "7.2.0",
53 + "semver": "6.3.0",
54 + "style-loader": "1.0.0",
55 + "terser-webpack-plugin": "1.4.1",
56 + "ts-pnp": "1.1.4",
57 + "url-loader": "2.1.0",
58 + "webpack": "4.41.0",
59 + "webpack-dev-server": "3.2.1",
60 + "webpack-manifest-plugin": "2.1.1",
61 + "workbox-webpack-plugin": "4.3.1"
62 },
63 "scripts": {
64 "prestart": "cp -r ../../build/node_modules/* ./node_modules/",
65 "prebuild": "cp -r ../../build/node_modules/* ./node_modules/",
66 "start": "concurrently \"npm run start:server\" \"npm run start:client\"",
15 - "start:client": "react-scripts start",
67 + "start:client": "node scripts/start.js",
68 "start:server": "NODE_ENV=development node server",
17 - "start:prod": "react-scripts build && NODE_ENV=production node server",
18 - "build": "react-scripts build",
19 - "test": "react-scripts test --env=jsdom",
20 - "eject": "react-scripts eject"
69 + "start:prod": "node scripts/build.js && NODE_ENV=production node server",
70 + "build": "node scripts/build.js",
71 + "test": "node scripts/test.js --env=jsdom"
72 },
73 "eslintConfig": {
74 "extends": "react-app"
@@ -33,5 +84,58 @@
84 "last 1 firefox version",
85 "last 1 safari version"
86 ]
87 + },
88 + "jest": {
89 + "roots": [
90 + "<rootDir>/src"
91 + ],
92 + "collectCoverageFrom": [
93 + "src/**/*.{js,jsx,ts,tsx}",
94 + "!src/**/*.d.ts"
95 + ],
96 + "setupFiles": [
97 + "react-app-polyfill/jsdom"
98 + ],
99 + "setupFilesAfterEnv": [],
100 + "testMatch": [
101 + "<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}",
102 + "<rootDir>/src/**/*.{spec,test}.{js,jsx,ts,tsx}"
103 + ],
104 + "testEnvironment": "jest-environment-jsdom-fourteen",
105 + "transform": {
106 + "^.+\\.(js|jsx|ts|tsx)$": "<rootDir>/node_modules/babel-jest",
107 + "^.+\\.css$": "<rootDir>/config/jest/cssTransform.js",
108 + "^(?!.*\\.(js|jsx|ts|tsx|css|json)$)": "<rootDir>/config/jest/fileTransform.js"
109 + },
110 + "transformIgnorePatterns": [
111 + "[/\\\\]node_modules[/\\\\].+\\.(js|jsx|ts|tsx)$",
112 + "^.+\\.module\\.(css|sass|scss)$"
113 + ],
114 + "modulePaths": [],
115 + "moduleNameMapper": {
116 + "^react-native$": "react-native-web",
117 + "^.+\\.module\\.(css|sass|scss)$": "identity-obj-proxy"
118 + },
119 + "moduleFileExtensions": [
120 + "web.js",
121 + "js",
122 + "web.ts",
123 + "ts",
124 + "web.tsx",
125 + "tsx",
126 + "json",
127 + "web.jsx",
128 + "jsx",
129 + "node"
130 + ],
131 + "watchPlugins": [
132 + "jest-watch-typeahead/filename",
133 + "jest-watch-typeahead/testname"
134 + ]
135 + },
136 + "babel": {
137 + "presets": [
138 + "react-app"
139 + ]
140 }
141 }
fixtures/flight/scripts/build.js new
+200
@@ -0,0 +1,200 @@
1 +'use strict';
2 +
3 +// Do this as the first thing so that any code reading it knows the right env.
4 +process.env.BABEL_ENV = 'production';
5 +process.env.NODE_ENV = 'production';
6 +
7 +// Makes the script crash on unhandled rejections instead of silently
8 +// ignoring them. In the future, promise rejections that are not handled will
9 +// terminate the Node.js process with a non-zero exit code.
10 +process.on('unhandledRejection', err => {
11 + throw err;
12 +});
13 +
14 +// Ensure environment variables are read.
15 +require('../config/env');
16 +
17 +const path = require('path');
18 +const chalk = require('react-dev-utils/chalk');
19 +const fs = require('fs-extra');
20 +const webpack = require('webpack');
21 +const configFactory = require('../config/webpack.config');
22 +const paths = require('../config/paths');
23 +const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
24 +const formatWebpackMessages = require('react-dev-utils/formatWebpackMessages');
25 +const printHostingInstructions = require('react-dev-utils/printHostingInstructions');
26 +const FileSizeReporter = require('react-dev-utils/FileSizeReporter');
27 +const printBuildError = require('react-dev-utils/printBuildError');
28 +
29 +const measureFileSizesBeforeBuild =
30 + FileSizeReporter.measureFileSizesBeforeBuild;
31 +const printFileSizesAfterBuild = FileSizeReporter.printFileSizesAfterBuild;
32 +const useYarn = fs.existsSync(paths.yarnLockFile);
33 +
34 +// These sizes are pretty large. We'll warn for bundles exceeding them.
35 +const WARN_AFTER_BUNDLE_GZIP_SIZE = 512 * 1024;
36 +const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024;
37 +
38 +const isInteractive = process.stdout.isTTY;
39 +
40 +// Warn and crash if required files are missing
41 +if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
42 + process.exit(1);
43 +}
44 +
45 +// Generate configuration
46 +const config = configFactory('production');
47 +
48 +// We require that you explicitly set browsers and do not fall back to
49 +// browserslist defaults.
50 +const {checkBrowsers} = require('react-dev-utils/browsersHelper');
51 +checkBrowsers(paths.appPath, isInteractive)
52 + .then(() => {
53 + // First, read the current file sizes in build directory.
54 + // This lets us display how much they changed later.
55 + return measureFileSizesBeforeBuild(paths.appBuild);
56 + })
57 + .then(previousFileSizes => {
58 + // Remove all content but keep the directory so that
59 + // if you're in it, you don't end up in Trash
60 + fs.emptyDirSync(paths.appBuild);
61 + // Merge with the public folder
62 + copyPublicFolder();
63 + // Start the webpack build
64 + return build(previousFileSizes);
65 + })
66 + .then(
67 + ({stats, previousFileSizes, warnings}) => {
68 + if (warnings.length) {
69 + console.log(chalk.yellow('Compiled with warnings.\n'));
70 + console.log(warnings.join('\n\n'));
71 + console.log(
72 + '\nSearch for the ' +
73 + chalk.underline(chalk.yellow('keywords')) +
74 + ' to learn more about each warning.'
75 + );
76 + console.log(
77 + 'To ignore, add ' +
78 + chalk.cyan('// eslint-disable-next-line') +
79 + ' to the line before.\n'
80 + );
81 + } else {
82 + console.log(chalk.green('Compiled successfully.\n'));
83 + }
84 +
85 + console.log('File sizes after gzip:\n');
86 + printFileSizesAfterBuild(
87 + stats,
88 + previousFileSizes,
89 + paths.appBuild,
90 + WARN_AFTER_BUNDLE_GZIP_SIZE,
91 + WARN_AFTER_CHUNK_GZIP_SIZE
92 + );
93 + console.log();
94 +
95 + const appPackage = require(paths.appPackageJson);
96 + const publicUrl = paths.publicUrl;
97 + const publicPath = config.output.publicPath;
98 + const buildFolder = path.relative(process.cwd(), paths.appBuild);
99 + printHostingInstructions(
100 + appPackage,
101 + publicUrl,
102 + publicPath,
103 + buildFolder,
104 + useYarn
105 + );
106 + },
107 + err => {
108 + const tscCompileOnError = process.env.TSC_COMPILE_ON_ERROR === 'true';
109 + if (tscCompileOnError) {
110 + console.log(
111 + chalk.yellow(
112 + 'Compiled with the following type errors (you may want to check these before deploying your app):\n'
113 + )
114 + );
115 + printBuildError(err);
116 + } else {
117 + console.log(chalk.red('Failed to compile.\n'));
118 + printBuildError(err);
119 + process.exit(1);
120 + }
121 + }
122 + )
123 + .catch(err => {
124 + if (err && err.message) {
125 + console.log(err.message);
126 + }
127 + process.exit(1);
128 + });
129 +
130 +// Create the production build and print the deployment instructions.
131 +function build(previousFileSizes) {
132 + // We used to support resolving modules according to `NODE_PATH`.
133 + // This now has been deprecated in favor of jsconfig/tsconfig.json
134 + // This lets you use absolute paths in imports inside large monorepos:
135 + if (process.env.NODE_PATH) {
136 + console.log(
137 + chalk.yellow(
138 + 'Setting NODE_PATH to resolve modules absolutely has been deprecated in favor of setting baseUrl in jsconfig.json (or tsconfig.json if you are using TypeScript) and will be removed in a future major release of create-react-app.'
139 + )
140 + );
141 + console.log();
142 + }
143 +
144 + console.log('Creating an optimized production build...');
145 +
146 + const compiler = webpack(config);
147 + return new Promise((resolve, reject) => {
148 + compiler.run((err, stats) => {
149 + let messages;
150 + if (err) {
151 + if (!err.message) {
152 + return reject(err);
153 + }
154 + messages = formatWebpackMessages({
155 + errors: [err.message],
156 + warnings: [],
157 + });
158 + } else {
159 + messages = formatWebpackMessages(
160 + stats.toJson({all: false, warnings: true, errors: true})
161 + );
162 + }
163 + if (messages.errors.length) {
164 + // Only keep the first error. Others are often indicative
165 + // of the same problem, but confuse the reader with noise.
166 + if (messages.errors.length > 1) {
167 + messages.errors.length = 1;
168 + }
169 + return reject(new Error(messages.errors.join('\n\n')));
170 + }
171 + if (
172 + process.env.CI &&
173 + (typeof process.env.CI !== 'string' ||
174 + process.env.CI.toLowerCase() !== 'false') &&
175 + messages.warnings.length
176 + ) {
177 + console.log(
178 + chalk.yellow(
179 + '\nTreating warnings as errors because process.env.CI = true.\n' +
180 + 'Most CI servers set it automatically.\n'
181 + )
182 + );
183 + return reject(new Error(messages.warnings.join('\n\n')));
184 + }
185 +
186 + return resolve({
187 + stats,
188 + previousFileSizes,
189 + warnings: messages.warnings,
190 + });
191 + });
192 + });
193 +}
194 +
195 +function copyPublicFolder() {
196 + fs.copySync(paths.appPublic, paths.appBuild, {
197 + dereference: true,
198 + filter: file => file !== paths.appHtml,
199 + });
200 +}
fixtures/flight/scripts/start.js new
+146
@@ -0,0 +1,146 @@
1 +'use strict';
2 +
3 +// Do this as the first thing so that any code reading it knows the right env.
4 +process.env.BABEL_ENV = 'development';
5 +process.env.NODE_ENV = 'development';
6 +
7 +// Makes the script crash on unhandled rejections instead of silently
8 +// ignoring them. In the future, promise rejections that are not handled will
9 +// terminate the Node.js process with a non-zero exit code.
10 +process.on('unhandledRejection', err => {
11 + throw err;
12 +});
13 +
14 +// Ensure environment variables are read.
15 +require('../config/env');
16 +
17 +const fs = require('fs');
18 +const chalk = require('react-dev-utils/chalk');
19 +const webpack = require('webpack');
20 +const WebpackDevServer = require('webpack-dev-server');
21 +const clearConsole = require('react-dev-utils/clearConsole');
22 +const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
23 +const {
24 + choosePort,
25 + createCompiler,
26 + prepareProxy,
27 + prepareUrls,
28 +} = require('react-dev-utils/WebpackDevServerUtils');
29 +const openBrowser = require('react-dev-utils/openBrowser');
30 +const paths = require('../config/paths');
31 +const configFactory = require('../config/webpack.config');
32 +const createDevServerConfig = require('../config/webpackDevServer.config');
33 +
34 +const useYarn = fs.existsSync(paths.yarnLockFile);
35 +const isInteractive = process.stdout.isTTY;
36 +
37 +// Warn and crash if required files are missing
38 +if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
39 + process.exit(1);
40 +}
41 +
42 +// Tools like Cloud9 rely on this.
43 +const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000;
44 +const HOST = process.env.HOST || '0.0.0.0';
45 +
46 +if (process.env.HOST) {
47 + console.log(
48 + chalk.cyan(
49 + `Attempting to bind to HOST environment variable: ${chalk.yellow(
50 + chalk.bold(process.env.HOST)
51 + )}`
52 + )
53 + );
54 + console.log(
55 + `If this was unintentional, check that you haven't mistakenly set it in your shell.`
56 + );
57 + console.log(
58 + `Learn more here: ${chalk.yellow('https://bit.ly/CRA-advanced-config')}`
59 + );
60 + console.log();
61 +}
62 +
63 +// We require that you explicitly set browsers and do not fall back to
64 +// browserslist defaults.
65 +const {checkBrowsers} = require('react-dev-utils/browsersHelper');
66 +checkBrowsers(paths.appPath, isInteractive)
67 + .then(() => {
68 + // We attempt to use the default port but if it is busy, we offer the user to
69 + // run on a different port. `choosePort()` Promise resolves to the next free port.
70 + return choosePort(HOST, DEFAULT_PORT);
71 + })
72 + .then(port => {
73 + if (port == null) {
74 + // We have not found a port.
75 + return;
76 + }
77 + const config = configFactory('development');
78 + const protocol = process.env.HTTPS === 'true' ? 'https' : 'http';
79 + const appName = require(paths.appPackageJson).name;
80 + const useTypeScript = fs.existsSync(paths.appTsConfig);
81 + const tscCompileOnError = process.env.TSC_COMPILE_ON_ERROR === 'true';
82 + const urls = prepareUrls(protocol, HOST, port);
83 + const devSocket = {
84 + warnings: warnings =>
85 + devServer.sockWrite(devServer.sockets, 'warnings', warnings),
86 + errors: errors =>
87 + devServer.sockWrite(devServer.sockets, 'errors', errors),
88 + };
89 + // Create a webpack compiler that is configured with custom messages.
90 + const compiler = createCompiler({
91 + appName,
92 + config,
93 + devSocket,
94 + urls,
95 + useYarn,
96 + useTypeScript,
97 + tscCompileOnError,
98 + webpack,
99 + });
100 + // Load proxy config
101 + const proxySetting = require(paths.appPackageJson).proxy;
102 + const proxyConfig = prepareProxy(proxySetting, paths.appPublic);
103 + // Serve webpack assets generated by the compiler over a web server.
104 + const serverConfig = createDevServerConfig(
105 + proxyConfig,
106 + urls.lanUrlForConfig
107 + );
108 + const devServer = new WebpackDevServer(compiler, serverConfig);
109 + // Launch WebpackDevServer.
110 + devServer.listen(port, HOST, err => {
111 + if (err) {
112 + return console.log(err);
113 + }
114 + if (isInteractive) {
115 + clearConsole();
116 + }
117 +
118 + // We used to support resolving modules according to `NODE_PATH`.
119 + // This now has been deprecated in favor of jsconfig/tsconfig.json
120 + // This lets you use absolute paths in imports inside large monorepos:
121 + if (process.env.NODE_PATH) {
122 + console.log(
123 + chalk.yellow(
124 + 'Setting NODE_PATH to resolve modules absolutely has been deprecated in favor of setting baseUrl in jsconfig.json (or tsconfig.json if you are using TypeScript) and will be removed in a future major release of create-react-app.'
125 + )
126 + );
127 + console.log();
128 + }
129 +
130 + console.log(chalk.cyan('Starting the development server...\n'));
131 + openBrowser(urls.localUrlForBrowser);
132 + });
133 +
134 + ['SIGINT', 'SIGTERM'].forEach(function(sig) {
135 + process.on(sig, function() {
136 + devServer.close();
137 + process.exit();
138 + });
139 + });
140 + })
141 + .catch(err => {
142 + if (err && err.message) {
143 + console.log(err.message);
144 + }
145 + process.exit(1);
146 + });
fixtures/flight/scripts/test.js new
+51
@@ -0,0 +1,51 @@
1 +'use strict';
2 +
3 +// Do this as the first thing so that any code reading it knows the right env.
4 +process.env.BABEL_ENV = 'test';
5 +process.env.NODE_ENV = 'test';
6 +process.env.PUBLIC_URL = '';
7 +
8 +// Makes the script crash on unhandled rejections instead of silently
9 +// ignoring them. In the future, promise rejections that are not handled will
10 +// terminate the Node.js process with a non-zero exit code.
11 +process.on('unhandledRejection', err => {
12 + throw err;
13 +});
14 +
15 +// Ensure environment variables are read.
16 +require('../config/env');
17 +
18 +const jest = require('jest');
19 +const execSync = require('child_process').execSync;
20 +let argv = process.argv.slice(2);
21 +
22 +function isInGitRepository() {
23 + try {
24 + execSync('git rev-parse --is-inside-work-tree', {stdio: 'ignore'});
25 + return true;
26 + } catch (e) {
27 + return false;
28 + }
29 +}
30 +
31 +function isInMercurialRepository() {
32 + try {
33 + execSync('hg --cwd . root', {stdio: 'ignore'});
34 + return true;
35 + } catch (e) {
36 + return false;
37 + }
38 +}
39 +
40 +// Watch unless on CI or explicitly running all tests
41 +if (
42 + !process.env.CI &&
43 + argv.indexOf('--watchAll') === -1 &&
44 + argv.indexOf('--watchAll=false') === -1
45 +) {
46 + // https://github.com/facebook/create-react-app/issues/5210
47 + const hasSourceControl = isInGitRepository() || isInMercurialRepository();
48 + argv.push(hasSourceControl ? '--watch' : '--watchAll');
49 +}
50 +
51 +jest.run(argv);
fixtures/flight/yarn.lock
-64
@@ -4267,10 +4267,6 @@ fs.realpath@^1.0.0:
4267 version "1.0.0"
4268 resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
4269
4270 -fsevents@2.0.7:
4271 - version "2.0.7"
4272 - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.0.7.tgz#382c9b443c6cbac4c57187cdda23aa3bf1ccfc2a"
4273 -
4270 fsevents@^1.2.2:
4271 version "1.2.4"
4272 resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426"
@@ -7806,66 +7802,6 @@ react-is@^16.8.1, react-is@^16.8.4:
7802 version "16.11.0"
7803 resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.11.0.tgz#b85dfecd48ad1ce469ff558a882ca8e8313928fa"
7804
7809 -react-scripts@3.2.0:
7810 - version "3.2.0"
7811 - resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-3.2.0.tgz#58ccd6b4ffa27f1b4d2986cbdcaa916660e9e33c"
7812 - dependencies:
7813 - "@babel/core" "7.6.0"
7814 - "@svgr/webpack" "4.3.2"
7815 - "@typescript-eslint/eslint-plugin" "^2.2.0"
7816 - "@typescript-eslint/parser" "^2.2.0"
7817 - babel-eslint "10.0.3"
7818 - babel-jest "^24.9.0"
7819 - babel-loader "8.0.6"
7820 - babel-plugin-named-asset-import "^0.3.4"
7821 - babel-preset-react-app "^9.0.2"
7822 - camelcase "^5.2.0"
7823 - case-sensitive-paths-webpack-plugin "2.2.0"
7824 - css-loader "2.1.1"
7825 - dotenv "6.2.0"
7826 - dotenv-expand "5.1.0"
7827 - eslint "^6.1.0"
7828 - eslint-config-react-app "^5.0.2"
7829 - eslint-loader "3.0.2"
7830 - eslint-plugin-flowtype "3.13.0"
7831 - eslint-plugin-import "2.18.2"
7832 - eslint-plugin-jsx-a11y "6.2.3"
7833 - eslint-plugin-react "7.14.3"
7834 - eslint-plugin-react-hooks "^1.6.1"
7835 - file-loader "3.0.1"
7836 - fs-extra "7.0.1"
7837 - html-webpack-plugin "4.0.0-beta.5"
7838 - identity-obj-proxy "3.0.0"
7839 - is-wsl "^1.1.0"
7840 - jest "24.9.0"
7841 - jest-environment-jsdom-fourteen "0.1.0"
7842 - jest-resolve "24.9.0"
7843 - jest-watch-typeahead "0.4.0"
7844 - mini-css-extract-plugin "0.8.0"
7845 - optimize-css-assets-webpack-plugin "5.0.3"
7846 - pnp-webpack-plugin "1.5.0"
7847 - postcss-flexbugs-fixes "4.1.0"
7848 - postcss-loader "3.0.0"
7849 - postcss-normalize "7.0.1"
7850 - postcss-preset-env "6.7.0"
7851 - postcss-safe-parser "4.0.1"
7852 - react-app-polyfill "^1.0.4"
7853 - react-dev-utils "^9.1.0"
7854 - resolve "1.12.0"
7855 - resolve-url-loader "3.1.0"
7856 - sass-loader "7.2.0"
7857 - semver "6.3.0"
7858 - style-loader "1.0.0"
7859 - terser-webpack-plugin "1.4.1"
7860 - ts-pnp "1.1.4"
7861 - url-loader "2.1.0"
7862 - webpack "4.41.0"
7863 - webpack-dev-server "3.2.1"
7864 - webpack-manifest-plugin "2.1.1"
7865 - workbox-webpack-plugin "4.3.1"
7866 - optionalDependencies:
7867 - fsevents "2.0.7"
7868 -
7805 read-pkg-up@^2.0.0:
7806 version "2.0.0"
7807 resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be"
packages/react-flight-dom-webpack/npm/plugin.js new
+7
@@ -0,0 +1,7 @@
1 +'use strict';
2 +
3 +if (process.env.NODE_ENV === 'production') {
4 + module.exports = require('./cjs/react-flight-dom-webpack-plugin.production.min.js');
5 +} else {
6 + module.exports = require('./cjs/react-flight-dom-webpack-plugin.development.js');
7 +}
packages/react-flight-dom-webpack/package.json
+1
@@ -13,6 +13,7 @@
13 "LICENSE",
14 "README.md",
15 "index.js",
16 + "plugin.js",
17 "server.js",
18 "server.browser.js",
19 "server.node.js",
packages/react-flight-dom-webpack/plugin.js new
+10
@@ -0,0 +1,10 @@
1 +/**
2 + * Copyright (c) Facebook, Inc. and its affiliates.
3 + *
4 + * This source code is licensed under the MIT license found in the
5 + * LICENSE file in the root directory of this source tree.
6 + *
7 + * @flow
8 + */
9 +
10 +export {default} from './src/ReactFlightWebpackPlugin';
packages/react-flight-dom-webpack/src/ReactFlightWebpackPlugin.js new
+13
@@ -0,0 +1,13 @@
1 +/**
2 + * Copyright (c) Facebook, Inc. and its affiliates.
3 + *
4 + * This source code is licensed under the MIT license found in the
5 + * LICENSE file in the root directory of this source tree.
6 + *
7 + * @flow
8 + */
9 +
10 +export default class ReactFlightWebpackPlugin {
11 + constructor(options: {isServer: boolean}) {}
12 + apply(compiler: any) {}
13 +}
scripts/rollup/bundles.js
+20
@@ -246,6 +246,26 @@ const bundles = [
246 externals: ['react'],
247 },
248
249 + /******* React DOM Flight Webpack Plugin *******/
250 + {
251 + bundleTypes: [NODE_DEV, NODE_PROD],
252 + moduleType: RENDERER_UTILS,
253 + entry: 'react-flight-dom-webpack/plugin',
254 + global: 'ReactFlightWebpackPlugin',
255 + externals: [],
256 + babel: opts =>
257 + Object.assign({}, opts, {
258 + // Include JSX
259 + presets: opts.presets.concat([
260 + require.resolve('@babel/preset-react'),
261 + require.resolve('@babel/preset-flow'),
262 + ]),
263 + plugins: opts.plugins.concat([
264 + [require.resolve('@babel/plugin-transform-classes'), {loose: true}],
265 + ]),
266 + }),
267 + },
268 +
269 /******* React DOM Flight Server Relay *******/
270 {
271 bundleTypes: [FB_WWW_DEV, FB_WWW_PROD],