Webpack.docschina.org/blog/2020-1…
The introduction
Webpack released WebPack 5.0.0 in October 2020. As the core capability of front-end engineering, the Webpack team did not make a major API upgrade (ღ(´ · ᴗ ·)ღ) considering the learning cost of developers. Compared with Webpack 4, some core upgrade points were recorded and shared
Node.js Polyfills will no longer be introduced
Webpack 5 starts with a greater focus on front-end engineering builds and no longer automates filling Node Api gaskets to improve web builds
webpack 4
import { crypto } from 'crypto';
console.log('Node Module Test');
Copy the code
These polyfills are huge and waste performance, and webpack itself warns that we need to optimize them in other ways (polyfill.io).
webpack 5
import { crypto } from 'crypto';
console.log('Node WebPack5 module Test');
Copy the code
Webpack 5 no longer introduces and compiles failures, so you should configure Polyfill for these Node apis
If you use the Node module in your project, you can enable it by:
// webpack.config.js
module.exports = {
mode: 'production'.resolve: {
fallback: {
// Take Crypto as an example. If certain apis are used, the following configuration can be used for compatibility
"crypto": require.resolve("crypto-browserify"),
// Do not introduce gasket, can be closed by the following configuration
"crypto": false}}}Copy the code
Support resource module compilation
Webpack5 starts with the ability to compile various resource files built-in, JPG/GIF/TXT /.. Resource files no longer need to be compiled by file-loader, URl-loader and other resource processing loader.
Webpack now naturally supports the following module types
- ECMAScript module
- CommonJS module
- AMD modules
- Assets
- WebAssembly module
Previously, we used urL-loader to optimize some small files (< 1024 * 5 convert base64).
Now the rule configuration of the common resource class can be accomplished in the following ways:
// webpack.config.js
/ / way
module.exports = {
mode: 'production'./ / write one
module: {
generator: {
'asset': {},
'asset/inline': {},
'asset/resource': {},
'asset/source': {},}}/ / write two
module: {
parser: {
'asset': {},
'asset/inline': {},
'asset/resource': {},
'asset/source': {},}}/ / writing three
module: {
rules: [{test: /\.jpg$/.type: 'asset/resource'.parser: {},}, {test: /\.png$/.type: 'asset/inline'.parser: {},}, {test: /\.txt$/.type: 'asset/source'.parser: {},}]}}Copy the code
The corresponding modes of internal modules in WebPack 5 are as follows: asset/ Inline => URl-loader, asset/source => raw-loader, asset/resource => file-loader.
More details on the rules can be found here
Persistent compile cache mechanism updated
In WebPack 5, we have updated the cache strategy, which can greatly improve the speed of our development and compilation.
webpack 4
In WebPack < 5, we usually use the Babel plugin configuration or manifest.json file index to optimize build speed
webpack 5
Add test code:
// webpack.config.js
module.exports = {
mode: "production".module: {
rules: [{test: /\.(js|jsx)$/,
use: [
{
loader: "babel-loader".options: {
presets: [
"@babel/preset-react"]}}]}},plugins: [
new HtmlWebpackPlugin({
template: './public/index.html'}),],... }// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './app.jsx';
ReactDOM.render(<App />.document.getElementById('root'));
//app.jsx
import React from 'react';
import { fnA1 } from './moduleA';
class App extends React.Component {
componentDidMount() {
fnA1();
}
render() {
return <div>hello react</div>; }}export default App;
Copy the code
webpack --config webpack.config.js
Copy the code
The output from the two builds is as follows:
For the first time,
The second time
The twice build time was close to 3000ms, and then the webpack5 long cache mechanism was enabled
// webpack.config.js
module.exports = {
mode: "production".cache: {
type: "fileSystem"}... }Copy the code
On the second build, you can see a six-fold increase in speed.
Cache files can be found in node_modules/.cache/webpack, and the cache path can be modified through the cacheDirectory configuration.
In practical use, provide the fileSystem in webpack | two ways of memory, the memory cache will build products to improve the building speed in system memory, this model can only be used in development mode.
By default, WebPack 5 uses file + content for hash calculation in production mode build, and timestamp for caching mechanism in development mode, in conjunction with long-term caching algorithm mechanism. Webpackage 5 also updated the generation mechanism for moduleIds and chunkIds [see below].
Optimization of moduleIds, chunkIds changes
Module and chunk can be simply understood as a file before compilation and a product after compilation. A file corresponds to a module, and a code block corresponds to a chunk. Different chunks refer to each other. Typically, scripts that run on a browser are called bundles.
Prior to WebPack 5, asynchronous modules were printed in increments of numbers, so that the caching mechanism would fail in some cases
webpack4
Webpack4 adds code
// demo/index.js
import { comm1, comm2 } from './d';
(async() = > {await import('./a');
await import('./b');
await import('./c'); }) ()console.log(comm1, comm2);
// webpack.config.js
module.exports = {
mode: "production".optimization: {
splitChunks: {
chunks: 'all'.minSize: 500.minChunks: 1.cacheGroups: {
defaultVendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10.reuseExistingChunk: true,},default: {
minChunks: 2.priority: -20.reuseExistingChunk: true,},},},},}Copy the code
The compiled output is as follows:
webpack5
The same file, in WebPack 5, outputs a short numeric ID.
Webpack 5 will default to Production mode with chunkIds: “Deterministic” mode enabled to cache file contents at the content level.
More powerful tree-shaking
Another important optimization algorithm for Webpack is tree-shaking. Webpack 5 improves the tree-shaking algorithm further than WebPack4: Tree-shaking supports nested modules and internal modules tree-shaking
webpack 4
Add the code
// a.js
function a () {
console.log('a')
}
function b () {
console.log('b')
}
export default {
a, b
}
// index.js
import a from './a'
console.log(a.a());
console.log('hello world');
Copy the code
Webpack 4 build output:
Webpack 4 looks for the introduction of A.A () in module A, so module A is introduced.
webpack 5
For the same introduction and use, WebPack 5 is more intelligent and optimizes multiple dependency modules:
You can see that b is correctly removed.
Module federal
In addition to the key configuration or optimization changes mentioned above, WebPack has added a mode-federated loading mechanism for remote asynchronous loading bundles, which allows multiple WebPack build artifacts to work together. Allows you to import from a specified remote build and use remote JS bundles with minimal restrictions.
This loading mechanism is very suitable for the loading mode of the micro front end, because the mechanism of the micro front end itself is also cross-domain loading a section of JS script into the third-party module view.
The federated module test demo will be updated later.
conclusion
In general, in order to reduce the learning cost of developers, Webpack 5 optimizes the core algorithm and module optimization mechanism as little as possible, making Webpack more powerful without increasing our learning cost, which makes it easier to migrate and upgrade Webpack 5 for our old projects. Key update points can be summarized as follows:
- Persistent caching to improve build performance.
- More powerful Tree Shaking algorithm
- Increased compilation capabilities, with a greater focus on web build capabilities
- Better content-level hash algorithms improve long-term caching
- Solutions for modern complex business