Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.Sign up
Update to webpack 4 #809
For more details see the individual commit messages (most of the intermediate commits will fail to run standalone, but it still seemed preferable to split them up for easier review).
See here for the webpack 4 changelog:
I'd love to have any and all feedback - including:
To try this branch out locally with
Alternatively to use with an existing Neutrino 8 project:
Useful resources for reviewing:
Left to do:
I've updated the above instructions for trying out this branch to prevent leftover packages from causing problems. (If you see errors like
Preliminary builds using current and updated neutrino-preset-mozilla-frontend-infra on taskcluster-web:
Build time went from 154 seconds to 46 seconds. Incredible.
I noticed that in my updated preset, since the chunking logic is gone, I can no longer do this:
Does this mean that
Thank you for trying it out - nice improvement in build time! :-)
I think there's more caching going on by default now (
Yeah I'm pretty sure that should work.
Re the automatically generated chunk filenames - since this PR sets
As such, I was thinking of filing an issue against webpack asking for the default when
eliperelman left a comment
Whew, finally made it through everything!
Everything here looks good to me, with the caveat that this will need to be rebased due to the uglify/babel minification discussions, and the image minification middleware patch.
Looks great so far. We will see where webpack-chain v5 and other things take us.
Since webpack 4 now sets a default entry-point of `./src`, causing the error message to change for this test. (It doesn't seem worth creating the file to confirm it works, since from the error message we can tell the test got far enough that Neutrino correctly didn't complain about an explicit entry-point not being set.)
* Update webpack to ^4.6.0 * Update webpack-chain to ^4.6.0 * Update webpack-dev-server to ^3.1.3 * Update optimize-css-assets-webpack-plugin to ^4.0.0
Bases `mode` on `NODE_ENV`, falling back to `'development'` for anything but production, since otherwise minification (and more) would be enabled during testing. This is the same approach used in create-react-app's WIP webpack 4 PR. For the effects `mode` has, see: https://webpack.js.org/concepts/mode/ https://github.com/webpack/webpack/blob/v4.6.0/lib/WebpackOptionsDefaulter.js#L26-L294 https://github.com/webpack/webpack/blob/v4.6.0/lib/WebpackOptionsApply.js#L301-L342
Since it's now enabled by default when `mode` is `'production'`: https://github.com/webpack/webpack/blob/v4.6.0/lib/WebpackOptionsDefaulter.js#L213-L215 https://github.com/webpack/webpack/blob/v4.6.0/lib/WebpackOptionsApply.js#L317-L318
webpack 4 now has an intelligent chunking feature that replaces `CommonsChunkPlugin` and avoids the need to create the fake `vendor` entrypoint to separate out third-party dependencies: https://webpack.js.org/plugins/split-chunks-plugin/ In addition, several of the plugins previously used are automatically enabled when `mode` is development: https://github.com/webpack/webpack/blob/v4.6.0/lib/WebpackOptionsDefaulter.js#L250-L259 https://github.com/webpack/webpack/blob/v4.6.0/lib/WebpackOptionsApply.js#L325-L328 (Note this differs slightly from our previous implementation, but if this results in long-term caching issues, issues should be filed to change the defaults upstream, and only set here as a last resort). However since `splitChunks` creates an unknown number of chunks with unpredictable filenames, it's no longer possible to pass an exact chunks list to `html-webpack-plugin`'s `chunks` option. We also can't omit the `chunks` option entirely, since for multi-entrypoint builds that would result in all assets being included for every page. As such, until `html-webpack-plugin` natively supports `splitChunks`, we have to use `html-webpack-include-sibling-chunks` to dynamically generate the `chunks` list: https://github.com/fenivana/html-webpack-include-sibling-chunks-plugin With the switch to `splitChunks`, `@neutrinojs/chunk` becomes simple enough that it's not really worth keeping separate from the web preset, particularly given that it relies on the sibling chunks workaround to actually be useable anyway. Note that webpack enables `splitChunks` in development too (which is great for dev-prod parity, and fixes a bug I was hitting migrating an app to Neutrino 8), which is why our overrides are no longer inside the `NODE_ENV === 'production'` block.
Previously users were encouraged to create a fake `vendor` entrypoint which worked in conjunction with `@neutrinojs/chunk` to separate out third-party dependencies to a vendor chunk. However with `splitChunks`, manually specifying this entrypoint will actually result in larger builds - so we must ensure users correctly update their configuration.
Since the former is deprecated for CSS extraction, and is not compatible with webpack 4. The new plugin has a much simpler API: https://github.com/webpack-contrib/mini-css-extract-plugin I've also chosen to remove `css-hot-loader` - since it's unnecessary when using `style-loader` in development. ie option (2) from #802. (Once `mini-css-extract-plugin` supports HMR we can stop using `style-loader` entirely.) NB: `mini-css-extract-plugin` doesn't support having multiple plugin instances, so now we only have one instance for both standard CSS and module CSS. This will need testing to ensure everything still works.
Disabling `optimization.splitChunks` prevents hangs when running `yarn test`, and disabling `optimization.runtimeChunk` (which is enabled by the web preset) fixes zero tests being run. Example hang: https://travis-ci.org/mozilla-neutrino/neutrino-dev/jobs/369061914#L833
There's still a lot left untested, but this improves coverage significantly in the meantime.
We're going to stick with webpack 4's default of uglify-es for now, since it's much faster than babel-minify. Between that and the new webpack `optimization.minimize` and `optimization.minimizer` options, it's simpler to just document how to override the defaults directly, rather than provide a separate preset per alternative minifier.
It was required to work around a source map bug when using newer `webpack-sources` with `babel-minify-webpack-plugin`: webpack-contrib/babel-minify-webpack-plugin#68 However now that we're using `uglify-es` instead, we can stop pinning the `webpack-sources` version and pick up some of the bug/perf fixes: https://github.com/webpack/webpack-sources/releases
Looks like numbers are comparable within margin of error.
Looks like the Babel minify error is back with the sources unpinned:
Being able to remove that workaround for me was another of the benefits of dropping official babel-minify support - particularly since further webpack-sources performance improvements are coming (eg webpack/webpack-sources#23). Instead of holding everyone back on an old version just in case someone wants to use
Also my hunch is that the only reason we're seeing the sourcemap errors with babel-minify is because of the exact
I'm going to create a minimal testcase repository without Neutrino to give the babel-minify-webpack-plugin maintainers something more to go on (in retrospect doing this sooner would have increased the chance of webpack-contrib/babel-minify-webpack-plugin#68 being fixed).
So re-reading the babel-minify-webpack-plugin issue I see that it occurs for all source map variants apart from cheap (and cheap is pointless when minifying, since everything is on one line), so I guess that leaves telling people to just disable sourcemaps in production if using babel-minify. (Which seems reasonable; it's not our fault it's buggy)