If you’re bundling front-end assets, chances are you’re using a tool to do it. And that 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.
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:
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 [email protected]
If you’re using Webpack v4 or later, you’ll also need to install the CLI:
npm install --save-dev webpack-cli
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:
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.
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
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 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
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
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
Since there are far too many config updates to list you can read all about the config changes via the v5 changelog.
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.
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
Deploying a Node-based web app or website is the easy part. Making sure your Node instance continues to serve resources to your app is where things get tougher. If you’re interested in ensuring requests to the backend or third-party services are successful, try LogRocket.
LogRocket is like a DVR for web and mobile apps, recording literally everything that happens while a user interacts with your app. Instead of guessing why problems happen, you can aggregate and report on problematic network requests to quickly understand the root cause.
LogRocket instruments your app to record baseline performance timings such as page load time, time to first byte, slow network requests, and also logs Redux, NgRx, and Vuex actions/state. Start monitoring for free.
Hey there, want to help make our blog better?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowLearn how to manage memory leaks in Rust, avoid unsafe behavior, and use tools like weak references to ensure efficient programs.
Bypass anti-bot measures in Node.js with curl-impersonate. Learn how it mimics browsers to overcome bot detection for web scraping.
Handle frontend data discrepancies with eventual consistency using WebSockets, Docker Compose, and practical code examples.
Efficient initializing is crucial to smooth-running websites. One way to optimize that process is through lazy initialization in Rust 1.80.