If you’re bundling front-end assets, chances are you’re using a tool to do it. And hat tool most likely is Webpack. In this article, I’ll be sharing some new features coming to Webpack 5, and what you should be aware of as you continue to use it in your daily work.
This new release is jam-packed with tons of new goodies and while I won’t detail every new feature, I will share the few that are important as outlined by the core team.
What’s expected
As of this writing, the v5 release is still in its early stages and may still be broken, however, the major version has breaking changes and some plugins might no longer work as expected. Webpack tries to provide compatibility layers when possible although some of the changes make this difficult (especially regarding the injection of additional runtime code). If a plugin isn’t working you should report it here (you can also read the full changelog here). You should also be aware that the minimum supported Node.js version has increased from 6 to 8 for Webpack 5.
In general, the v5 release focuses on a few key components:
- improving build performance with persistent caching
- improving long-term caching with better algorithms and defaults
- cleaning up internal structures without introducing any breaking changes,
- preparing for future features by introducing breaking changes now, and allowing the team to stay on v5 for as long as possible
Once again, here’s the full changelog, but definitely make sure to read up until the configuration changes to keep up-to-date.
To test out the work for v5 you can install it using the following command:
npm install —save-dev webpack@next
This command references the latest alpha version, but you can also install diff versions of progress with v5 using their tags via Webpack’s repository with the following command:
npm install —save-dev webpack@v5.0.0-alpha.9
If you’re using Webpack v4 or later, you’ll also need to install the CLI:
npm install --save-dev webpack-cli
Deprecated items
All items deprecated in v4 have been removed for v5. When migrating to v5 make sure that your Webpack 4 build doesn’t print deprecation warnings. If you’re experiencing issues regarding errors try to omit the stats option or don't use a preset. That said, things are still in pre-release stages so it is always best to ask the Webpack team via GitHub.
There are a few things that were also removed, but didn’t have deprecation warnings in v4 such as IgnorePlugin and BannerPlugin that must now be passed an options object. The following is an example that can be used for IgnorePlugin as the current documentation doesn’t appear to outline this:
new webpack.IgnorePlugin({ resourceRegExp: regex })
Reference:
Automatic Node.js polyfills removed
Back in the day, Webpack’s aim was to allow for running most node.js modules in the browser, but the module landscape changed and many module uses are now written specifically for front-end purposes. Versions <= 4 shipped with polyfills for a good majority of Node.js core modules that are automatically applied once a module uses any core modules.
This, in turn, added these large polyfills to the final bundle but were generally unnecessary. The attempts in v5 are to automatically stop polyfilling these core modules and focuses on front-end compatible ones.
When migrating to v5, it would be best to use front-end compatible modules when possible and manually add a polyfill for core modules when possible (error messages can help guide you). Feedback is appreciated/encouraged for the core team as this change may or may not make it into the final v5 release.
Deterministic chunk and module IDs
New algorithms have been added in order to assist with long term caching, and is enabled in production mode with the following configuration lines:
chunkIds: "deterministic”,
moduleIds: “deterministic"
The algorithms assign very short (3 or 4 character) numeric IDs to modules and chunks in a deterministic way. This is a trade-off between bundle size and long-term caching. When migrating from v4 it is best to use the default values for chunkIds and moduleIds. You can also opt-in to the old defaults from your config file:
chunkIds: "size”,
moduleIds: “size"
These lines will generate smaller bundles but invalidate them more often for caching.
Reference
- https://webpack.js.org/configuration/optimization/#optimization-moduleids
- https://webpack.js.org/configuration/optimization/#optimization-chunkids
Named chunk IDs
A newly named chunk id algorithm is now enabled by default in development mode that gives chunks (and filenames) human-readable references. A Module ID is determined by its path that’s relative to the context. A Chunk ID is determined by the chunk’s content so you no longer need to use:
import(/\* webpackChunkName: "name" \*/ "module")
The line above can be used for debugging, but it also makes sense if you wanna control the filenames for production environments. It is possible to use chunkIds: “named” in production just make sure not to expose sensitive information regarding module names accidentally.
optimization: { chunkIds: 'named' }
When migrating from v4 you might discover a dislike for filenames becoming altered in development mode. With that in mind you can pass the line below in order to use the old numeric mode from your config file.
chunkIds: “natural”
Reference
Compilers
Compilers will be required to close after use as they now enter and leave idle states as well as possess hooks for these states. Plugins may use these hooks to do unimportant work (i. e. the persistent cache slowly stores the cache to disk). When the compiler closes all remaining work should be completed ASAP. A callback will then signal the closing has been completed.
Plugins and their respective authors should expect that some users may forget to close the Compiler so all work should eventually be in the process of finishing up while in idle. Processes should also be prevented from exiting while the work is in progress. The webpack() facade automatically calls to close when passed a callback. When updating to v5 make sure while using the Node.js API to call Compiler.close upon completion of your work.
Reference
SplitChunks and module sizes
Modules now have the ability to express size in a better way as opposed to displaying a single number and have different types of sizes. The SplitChunksPlugin is now aware of how to handle these different sizes and uses them for minSize and maxSize. By default, only javascript size is handled, but you can now pass multiple values to manage them:
minSize: {
javascript: 30000,
style: 50000,
}
When migrating to v5 make sure to check which types of sizes are used in your build. This can be configured with splitChunks.minSize and optionally in splitChunks.maxSize.
Reference
Persistent caching
In v5 you’ll find an experimental filesystem cache that’s an opt-in feature enabled using the following line in your Webpack config file:
cache: { type: "filesystem” }
Right now, only the core feature set is ready. But when using it you must be aware of the limitations in order to avoid unexpected bugs. If you don’t fully understand these limitations, you’re probably better off avoiding this feature entirely until you’re really comfortable.
You’ll also have an automatic cache invalidation for resolving module source code and filesystem structure, but there’s no automatic cache invalidations for configurations and loader/plugin/core changes. If you’d like to manually cache invalidation there’s an option that can be used in your config with cache.version. It isn’t fully ready yet at the moment but you can make everything run smoothly by updating your cache.version when upgrading your tooling dependencies (webpack, loader, plugin) or when you change your configuration.
If you want to automate this, it might be best to hash webpack.config.js and node_modules/.yarn-integrity and pass them to cache.version and is likely how the Webpack team will do it internally.
When using the Persistent Cache, you don’t need the cache-loader anymore. The same is also true for babel cacheDirectory.
Reference
Config changes
Since there are far too many config updates to list you can read all about the config changes via the v5 changelog.
Internal changes
There are a handful of internal changes that are strictly relevant to plugin authors. You can read further about these internal changes should you need to reference them via the changelog.
Parting thoughts
Should you find an error that confuses or require further assistance make sure to file an issue with your question here or scroll through the comments posted by other developers as you may find an answer to your question before posting it.
If you find something missing in the changelog make sure to help the team and report it here. Currently, every Webpack contributor has write access, and those who don’t are encouraged to send a pull request.
Finally, make sure to try upgrading with the latest alpha version before reporting your issue as it may already be fixed. Happy bundling!
Helpful Links & Resources
- https://github.com/webpack/webpack
- https://webpack.js.org/configuration
- https://webpack.js.org/concepts
Plug: LogRocket, a DVR for web apps
LogRocket is a frontend logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.
In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single page apps.
Top comments (0)