new-webpack: only minify in prod (#566)

Summary:
Extraction of the plugin list to a function is mostly trivial, but
requires a novel `// $ExpectFlowError`. The error has been there the
whole time, but Flow only catches it now. Why? Who knows.

Test Plan:
Run

```
NODE_ENV=development node ./node_modules/.bin/webpack-dev-server \
    --config config/makeWebpackConfig.js
```

Note that the compilation/recompilation time is much faster than
previously.

wchargin-branch: webpack-minify-prod-only
This commit is contained in:
William Chargin 2018-07-30 17:11:30 -07:00 committed by GitHub
parent fca43f4362
commit 37eddcaf27
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -21,7 +21,7 @@ const publicUrl = publicPath.slice(0, -1);
// Get environment variables to inject into our app. // Get environment variables to inject into our app.
const env = getClientEnvironment(publicUrl); const env = getClientEnvironment(publicUrl);
function makeConfig(_unused_mode /*: "production" | "development" */) { function makeConfig(mode /*: "production" | "development" */) {
return { return {
// Don't attempt to continue if there are any errors. // Don't attempt to continue if there are any errors.
bail: true, bail: true,
@ -174,9 +174,24 @@ function makeConfig(_unused_mode /*: "production" | "development" */) {
}, },
], ],
}, },
plugins: [ plugins: plugins(mode),
// Some libraries import Node modules but don't use them in the browser.
// Tell Webpack to provide empty mocks for them so importing them works.
node: {
dgram: "empty",
fs: "empty",
net: "empty",
tls: "empty",
child_process: "empty",
},
};
}
function plugins(mode /*: "development" | "production" */) {
const basePlugins = [
new StaticSiteGeneratorPlugin({ new StaticSiteGeneratorPlugin({
entry: "ssr", entry: "ssr",
// $ExpectFlowError(dynamic require)
paths: require(paths.appRouteData).routeData.map(({path}) => path), paths: require(paths.appRouteData).routeData.map(({path}) => path),
locals: {}, locals: {},
}), }),
@ -185,27 +200,6 @@ function makeConfig(_unused_mode /*: "production" | "development" */) {
// It is absolutely essential that NODE_ENV was set to production here. // It is absolutely essential that NODE_ENV was set to production here.
// Otherwise React will be compiled in the very slow development mode. // Otherwise React will be compiled in the very slow development mode.
new webpack.DefinePlugin(env.stringified), new webpack.DefinePlugin(env.stringified),
// Minify the code.
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
// Disabled because of an issue with Uglify breaking seemingly valid code:
// https://github.com/facebookincubator/create-react-app/issues/2376
// Pending further investigation:
// https://github.com/mishoo/UglifyJS2/issues/2011
comparisons: false,
},
mangle: {
safari10: true,
},
output: {
comments: false,
// Turned on because emoji and regex is not minified properly using default
// https://github.com/facebookincubator/create-react-app/issues/2488
ascii_only: true,
},
sourceMap: shouldUseSourceMap,
}),
// Generate a manifest file which contains a mapping of all asset filenames // Generate a manifest file which contains a mapping of all asset filenames
// to their corresponding output file so that tools can pick it up without // to their corresponding output file so that tools can pick it up without
// having to parse `index.html`. // having to parse `index.html`.
@ -248,17 +242,38 @@ function makeConfig(_unused_mode /*: "production" | "development" */) {
// https://github.com/jmblog/how-to-optimize-momentjs-with-webpack // https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
// You can remove this if you don't use Moment.js: // You can remove this if you don't use Moment.js:
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/), new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
], ];
// Some libraries import Node modules but don't use them in the browser. const prodOnlyPlugins = [
// Tell Webpack to provide empty mocks for them so importing them works. // Minify the code.
node: { new webpack.optimize.UglifyJsPlugin({
dgram: "empty", compress: {
fs: "empty", warnings: false,
net: "empty", // Disabled because of an issue with Uglify breaking seemingly valid code:
tls: "empty", // https://github.com/facebookincubator/create-react-app/issues/2376
child_process: "empty", // Pending further investigation:
// https://github.com/mishoo/UglifyJS2/issues/2011
comparisons: false,
}, },
}; mangle: {
safari10: true,
},
output: {
comments: false,
// Turned on because emoji and regex is not minified properly using default
// https://github.com/facebookincubator/create-react-app/issues/2488
ascii_only: true,
},
sourceMap: shouldUseSourceMap,
}),
];
switch (mode) {
case "development":
return basePlugins;
case "production":
return basePlugins.concat(prodOnlyPlugins);
default:
throw new Error(/*:: (*/ mode /*: empty) */);
}
} }
function getMode() { function getMode() {