Skip to content
Created: March 27, 2021

Main new features and improvements in Webpack 5 ​

1. Module Federation✨——Micro front-end artifact ​

This is the most important feature of Webpack 5. Allows dynamic sharing of modules between multiple independently built applications, and even loads remote components/code at runtime.

Applies to:

  • Micro front-end architecture
  • Large-scale system for multi-team collaboration
  • Dynamically load remote modules on demand

Advantages:

  • No need to package common code into multiple bundles
  • Allow different projects to use different versions of dependencies (version conflicts are automatically handled)
  • Really realize “application-level lazy loading”

2. Better Persistent Caching🚀 The build speed is greatly improved ​

Webpack 5 introduced File system level persistent cache (filesystem cache), especially the second build can be significantly accelerated.

Effect:

  • Persistent caching reuses build results for unchanged modules.
  • Improvement depends on module count, loaders and invalidation; measure it.

Usage (explicitly enable filesystem caching; development defaults to memory caching and production disables it):

js
cache: {
  type: 'filesystem'
}

3. Tree Shaking improvements with built-in multiple optimizations (improved side effect analysis) ​

Webpack 5 will be better at determining which code is "pure function/no side effects", thus reducing dead code.

New capabilities:

  • More accurate identification of modules without side effects (package.json → "sideEffects": false)
  • Improving Dead Code Elimination in production environments

4. Remove Node.js Polyfills (improve web standards while reducing bundle size) ​

Webpack 4 will automatically polyfill Node core modules (such as buffer, stream), and Webpack 5 will no longer introduce them by default.

Benefits:

  • smaller bundles
  • More consistent with browser operating environment

Impact (if you still want to use it):

js
resolve: {
  fallback: {
    "crypto": false,
    "stream": require.resolve("stream-browserify"),
  }
}

5. Asset Modules (unified resource loader) are supported by default🖼️ ​

Webpack 5 adds Asset Modules, replacing various loaders:

Previously required:

  • file-loader
  • url-loader
  • raw-loader

Now use it uniformly:

js
type: 'asset/resource'
type: 'asset/inline'
type: 'asset/source'
type: 'asset'

Advantages:

  • Configuration is simpler
  • Intelligently choose whether to inline or send a separate file (can automatically determine the file size)

6. Improved Code Splitting & Smarter Chunk Splitting ​

Webpack 5 improves SplitChunks:

  • Analyze dependency graphs more intelligently
  • Less duplicate code
  • More stable chunk naming (improved cache hit rate)

7. Stronger Long-Term Caching capability 🧠 ​

Webpack 5 has optimized the following:

  • chunk IDs (more stable)
  • module IDs (more stable)
  • Improvement of hashing algorithm (really only hash changed module)

Result:

  • Improved browser cache hit rate
  • Fewer resources for users to update when releasing a new version

8. Better WebAssembly support (native support)🧩 ​

Webpack 5:

  • Supports standard WebAssembly
  • Improve asynchronous loading

Make the combination of JS and WASM smoother.

9. Built-in stronger development experience ​

Includes:

  • Faster HMR (hot updates)
  • better error logging
  • Automatically clean up old resources
  • Defaults to more stringent dependency analysis to detect potential problems in advance

📌 Summary sentence ​

The core improvements of Webpack 5 are: Module Federation, persistent cache, Asset Modules, optimized Tree Shaking, improved long-term caching mechanism, and removal of Node polyfills to reduce bundle size.The overall goal is to be faster, lighter, and better suited for micro-frontends and modern web architectures.

webpack optimizes packaging speed 【 2021 Summary 】 ​

Packaging performance analysis plug-in speed-measue-webpack-plugin

webpack packaging process ​

  1. Find the entry file according to the configuration file
  2. Parse the entry file through the loader
  3. Parse js code through acorn, generate ast syntax tree, find dependency files according to the syntax tree, and generate dependency graph
  4. Generate chunk packages based on dependency graph packaging

Abstract syntax tree demonstration

You can get the reference module through the value under source under importDeclaration.Stop until the file has no dependencies

Time-consuming steps: loader parsing, searching, and packaging time-consuming

Reduce parsing time ​

There are two ideas:😉

  1. Reduce the number of files to process and narrow the search scope
  2. Enable multi-process parsing

1. Reduce the processing of files and narrow the search scope

  1. noParse ignores files that do not need to be parsed. Syntax such as import and require cannot be used in ignored module files.
  2. Specify resolve.extensions so that when no extension is added, it will try to match the added extension in turn.
  3. Setting resolve.alias to specify specific paths and files can also speed up the search.
  4. resolve.modules specifies the search directory
  5. Add oneOf to module.rules so that the rules will only match once and will not continue to search after finding one.
  6. Add externals when the file is to be globally available in the browser.For example, jquery can be accessed through the module jquery or through window
  7. rules.include exclude refers to which files need to be parsed or not

2. Start multiple processes
Multi-process speeds up loader parsing time Because the author of happyPack no longer maintains it, it is recommended to use thread-loader
put this loader in front of other loaders. the following loaders run in a worker pool.

The specified module can be loaded into the cache by preheating the worker pool.

To prevent the high delay when booting workers it possible to warmup the worker pool.

This boots the max number of workers in the pool and loads specified modules into the node.js module cache.

cache-loader should also be placed at the front. If it is used at the same time as thread-loader, it is recommended that thread-loader be turned on first.

Turn on webpack's cache

Cache the generated webpack modules and chunks to improve build speed.

  • cache-loader Generate cacheKey based on the version number file name as the file name to see if the file exists. If it exists, compare it. mtime(modify time) , if the return cache is the same, if the loader below is different, it is a lightweight one that does not compare the content.
  • babel-loader generates a cacheKey as the file name through the file, option, and version number. It reads whether the file already exists. If it exists, the cache is used. If it does not exist, use bable-core to escape, zlib compression, and fs to write to the cache. It caches according to the file content.It does not affect other loaders.

Webpack loader detailed explanation click ​

The loader first executes its pitch method from left to right, and then executes their normal method from right to left.

Reduce search time ​

  1. Specify resolve.extensions so that when no extension is added, it will try to match the added extension in turn.
  2. Setting resolve.alias to specify specific paths and files can also speed up the search.
  3. resolve.modules specifies the search directory

Shorten packaging time ​

  1. Generate cache chunk When mode is development, the default configuration is cache:true
  2. smaller == faster Use fewer and smaller libraries.Use SplitChunksPlugin to remove unreferenced code in multi-page applications
js
optimization:{
    splitchunks: {
        chunks: 'all', // 默认只分割异步代码
        minSize: 0, // 分割出去的代码块的最小体积,0表示不限制
        maxSize: 0, // 分割出去的代码块的最大体积,0表示不限制
        minRemainingSize: 0, // 分割后剩下的体积,0表示不限制 webpack5新参数
        minChunks: 1,// 被多个入口引入几次会被分割
        maxAsyncRequest: 6, // 异步请求最大分割几个代码块
        maxInitialRequesta:6, // 同步请求,入口并行加载的最大请求数
        automaticNameDelimiter: '~', // 名称的分隔符
        enforceSizeThreshold: 50000, // 强制阈值, webpack5新参数
        cacheGroups: { // 缓存组配置, 配置如何对模块分组,相同分组会分到一个代码块中
            defaultVendors: { // 第三方模块
                test: /[\\/]node_modules[\\/]/, // 如果模块的路径匹配此正则
                priority: -10, // 优先级, 有很多缓存组,如果一个模块同属于多个缓存组,则哪个优先级高分到哪里
                reuseExitsingChunk: true, // 是否复用现有的代码块
            },
            default: {
                minChunks: 2, // 此模块被最少2次引用会被提取
                priority: -20, 
                reuseExistingChunk: true
            }
        }
    }
}

Others ​

With the improved performance of webpack 4, DLL is no longer of much use. You can also use hard-source-webpack-plugin.

noParse files that do not need to be parsed

IgnorePlugin ignores language files and the like

webpack compilation size optimization ​

Compress js, css, html and images

  • mini-css-extract-plugin extracts the mixed css in the js code (otherwise the css can only be parsed by executing js)

    In general style-loader Change to miniCssExtractPlugin.loader

    js
    module:{
        rules:[
            // 抽离 css
            {
                test: /\.css$/,
                loader: [
                    MiniCssExtractPlugin.loader,  // 注意,这里不再用 style-loader
                    'css-loader',
                    'postcss-loader'
                ]
            },
            // 抽离 less --> css
            {
                test: /\.less$/,
                loader: [
                    MiniCssExtractPlugin.loader,  // 注意,这里不再用 style-loader
                    'css-loader',
                    'less-loader',
                    'postcss-loader'
                ]
            }]
    }

    in plugins

    js
    plugins: [
        new miniCssExtractPlugin({
            filename: 'css/main.[contentHash:8].css'
        })
    ]
  • optimize-css-assets-webpack-plugin optimizes and compresses css resource files

    js
    optimization:{
        minimize: true, // 开启最小化
        minimizer:[new TerserJSPlugin({}), // 压缩js
        new OptimizeCSSAssetsPlugin({}) // 压缩css
        ]
    }
  • terser-webpack-plugin optimizes and compresses js resources

  • image-webpack-plugin compresses and optimizes images

    js
    module:{
        rules: [
            {
                test: /\.(png|jpg|jp?g|gif)$/,
                use: [{
                    loader: 'url-loader',
                    options: {
                        // 小于 5kb 的图片用 base64 格式产出
                        // 否则,依然延用 file-loader 的形式,产出 url 格式
                        limit: 5 * 1024,
    
                        // 打包到 img 目录下
                        outputPath: '/img1/',
    
                        // 设置图片的 cdn 地址(也可以统一在外面的 output 中设置,那将作用于所有静态资源)
                        // publicPath: 'http://cdn.abc.com'
                    }
                },{
                    {
                        loader:'image-webpack-loader',
                        options:{
                            mozjpeg:{
                                progressive: true,
                            },
                            optipng: {
                                enabled: false
                            },
                            pngquant: {
                                quality: [0.65, 0.90],
                                speed: 4
                            },
                            gifsicle:{
                                interlaced: false,
                            },
                            webp: {
                                quality: 75
                            }
                        },
                    }
                }]
            },
        ]
    }
  • Compress html files

    js
    plugins:[
        new HtmlWebpackPlugin({
            template:'./src/index.html',
            minify:{
                collapseWhitespace: true, // 去掉空格
                removeComments: true // 去掉注释
            }
        })
    ]
  • purgecss-webpack-plugin clears unused css

    js
    new PurgecssWebpackPlugin({
        paths: global.blob.sync(`${PATHS.src}/**/*`,{nodir: true}); // ** 匹配任意字符,包括路径分割符。   * 匹配任意字符,但不包括路径分隔符
        // const glob = require('glob') // 文件的匹配模式
        // const PATHS = {
        //    src: path.resolve(__dirname, 'src'),
        // }
    })