Webpack 5 正式发布至今,已经成为前端工程化领域一次规模空前的升级,不少开发者调侃它是向前端构建工具宇宙发起的一次全面进攻,用英文夸张点说就是 Assault Universe,袭击了整个宇宙。这个说法虽然带有玩笑成分,但 Webpack 5 带来的变化确实足够深远:持久化缓存让二次构建快得离谱,模块联邦让微前端架构的实现成本大幅降低,资源模块把一堆 loader 从配置文件里清除出去。如果你还在用 Webpack 4,这篇文章会帮你理清 Webpack 5 究竟强在哪里,以及升级时需要注意什么。

持久化缓存:二次构建速度的质变
Webpack 4 时代的缓存只存在于内存中,只要构建进程结束,缓存就随之消失。对于大型项目来说,每次冷启动都要完整走一遍解析、转换、打包流程,动辄几分钟的等待让人抓狂。Webpack 5 引入了基于文件系统的持久化缓存(File System Caching),第一次构建时把模块解析结果、转换后的代码、依赖图等信息写入 node_modules/.cache/webpack 目录,之后的构建直接从磁盘读取缓存,速度提升往往能达到数倍。
开启方式非常简单,只需要在配置中加一段:
module.exports = {
cache: {
type: 'filesystem',
buildDependencies: {
// 推荐把配置文件本身作为构建依赖,配置变更时缓存自动失效
config: [__filename]
}
}
};
这里有一个容易被忽视的细节:buildDependencies 的作用是声明哪些文件会影响构建结果。如果没有把 webpack 配置文件、babel 配置文件加进去,一旦修改了这些文件,缓存可能不会失效,导致构建产物与预期不符的诡异问题。建议把所有会影响编译结果的配置文件都列进去,宁可缓存多失效几次,也不要让旧缓存污染产物。
另外要注意,持久化缓存对 CI 环境的帮助取决于缓存能否被正确恢复。如果你的 CI 流水线每次都是全新的容器,又没有做缓存归档与还原,那么这项特性的收益会大打折扣。可以配合 CI 工具的缓存机制,把 node_modules/.cache 目录缓存下来,效果会非常明显。
模块联邦:微前端的官方级解决方案
模块联邦(Module Federation)可以说是 Webpack 5 最有想象力的特性。它允许多个独立构建、独立部署的应用在运行时共享模块,一个应用可以动态加载另一个应用暴露出来的组件、函数甚至整个页面,而且共享的依赖只会被加载一次。
举个典型场景:主应用和子应用都用到了 React,传统微前端方案里两者可能各自加载一份 React,体积和内存都翻倍。而模块联邦通过 shared 配置让双方协商,运行时只保留一份 React 实例。配置示例如下:
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');
module.exports = {
plugins: [
new ModuleFederationPlugin({
name: 'remoteApp',
filename: 'remoteEntry.js',
exposes: {
'./Button': './src/components/Button'
},
shared: {
react: { singleton: true },
'react-dom': { singleton: true }
}
})
]
};
exposes 声明了本应用对外暴露的模块,filename 是远程入口文件名。宿主应用通过 remotes 配置指向这个入口,就可以在代码里直接 import 远程模块,用起来和本地模块几乎没有区别。
需要提醒的是,singleton: true 表示该依赖全局只允许存在一个实例,这对 React 这类依赖单一实例的库是必须的,否则会报 hooks 调用异常。同时,共享依赖的版本协商也需要留意:如果宿主和子应用的版本差异过大,模块联邦会尝试加载兼容版本,失败时会在控制台给出警告。团队协作时最好约定好共享依赖的版本范围,避免运行时出现难以排查的冲突。
资源模块与 Tree Shaking 增强:配置瘦身
Webpack 5 用原生的 Asset Modules 取代了 file-loader、url-loader、raw-loader 这一整套资源加载器。现在处理图片、字体等文件,只需要一行 type: 'asset',Webpack 会根据文件大小自动决定内联为 base64 还是 emit 成单独文件,等于把 url-loader 的 limit 逻辑内置了。
module.exports = {
module: {
rules: [
{
test: /\.(png|jpe?g|gif|svg)$/i,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 8 * 1024 // 小于 8KB 内联,可根据项目调整
}
}
}
]
}
};
迁移时要把老的 loader 规则清理干净,否则新旧规则叠加可能出现资源被处理两次的问题。除了 asset,还有 asset/resource(始终 emit 文件)、asset/inline(始终内联)、asset/source(导出源码字符串)四种模式,按需选择即可。
Tree Shaking 方面,Webpack 5 支持了嵌套的无用代码消除,并且新增了对 CommonJS 模块的部分分析能力。更实用的是顶层的 await 支持和更好的代码生成算法,整体产物体积相比 Webpack 4 通常能减少几个百分点。虽然数字看起来不大,但对于大型应用来说,积少成多的收益相当可观。
迁移注意事项与升级建议
升级之前先确认项目依赖的插件和 loader 是否兼容 Webpack 5,尤其是 html-webpack-plugin、terser-webpack-plugin 这类核心插件,需要升级到对应的大版本。Node.js 版本也有要求,Webpack 5 最低需要 Node 10.13,实际生产环境建议直接用 Node 14 以上的长期支持版本。
另一个常见的迁移坑是 polyfill 的移除。Webpack 5 不再自动为 Node.js 核心模块注入 polyfill,如果代码里直接引用了 process、path 之类的模块,构建时会报错。解决办法有两个:要么在代码层面改造,通过 resolve.fallback 手动指定替代品,要么在入口处引入合适的 polyfill 包。这个报错在迁移初期会大量出现,属于正常现象,逐个处理即可。
总体来看,Webpack 5 值得升级的理由很充分:持久化缓存带来的构建提速是每天都在享受的收益,模块联邦为微前端提供了开箱即用的方案,资源模块则让配置文件更加干净。如果你的项目还停留在 Webpack 4,建议先在一个非核心项目上试水迁移,跑通流程后再推广到主力项目,把这次对构建工具宇宙的袭击变成自己的性能红利。
Webpack 5Module Federation持久化缓存修改时间:2026-09-06 13:38:36