Webpack 5 在开发阶段使用的代号是 Eerie Universe,中文社区常翻译成怪诞宇宙。这个代号听起来有些离奇,但这个大版本的改动确实够大:官方几乎重写了缓存子系统,移除了大量默认的 Node.js Polyfill,还带来了影响深远的模块联邦能力。如果你还在 Webpack 4 上观望,这篇文章会从实际项目角度出发,把这些新特性拆开讲清楚。

持久化缓存:二次构建速度的质变
Webpack 4 的缓存方案是 babel-loader 等工具各自为战的内存缓存,一旦进程退出,缓存就全部丢失。而 Webpack 5 引入了基于文件系统的持久化缓存,第一次构建时会把模块的解析结果、依赖关系、转换产物全部序列化到 node_modules/.cache/webpack 目录中,下次启动时直接反序列化恢复,跳过了大量重复的解析和转换工作。
开启方式非常简单,在配置中添加 cache: { type: 'filesystem' } 即可。默认策略下,Webpack 会根据依赖的时间戳来决定是否使用缓存,如果希望更严格的校验,可以把 buildDependencies 配置上 webpack 配置文件本身,这样配置一变缓存自动失效。
module.exports = {
cache: {
type: 'filesystem',
// 当这些文件变化时,缓存自动失效
buildDependencies: {
config: [__filename]
},
// 缓存版本号,重大变更时手动递增
version: '1.0.0'
}
};实际项目中,中型项目首次构建可能需要几十秒,但二次冷启动往往能降到两三秒,效果非常明显。需要注意的是,缓存依赖绝对路径,如果团队协作时把项目放在不同目录,或者频繁切换分支,命中率会下降。另外遇到诡异的构建结果时,第一反应应该是删掉缓存目录重试,这是排查持久化缓存问题的基本功。
模块联邦:微前端的官方解法
Eerie Universe 版本最有想象力的特性当属 Module Federation,也就是模块联邦。它允许多个独立构建、独立部署的应用在运行时互相共享模块。比如主应用和子应用分别打包部署,子应用可以把某个组件暴露出去,主应用远程异步加载它,两者甚至可以共享同一份 React 实例,避免出现多 React 实例导致的 hooks 报错。
使用时需要引入 webpack.container.ModuleFederationPlugin。提供方通过 exposes 暴露模块,通过 shared 声明共享依赖;消费方通过 remotes 声明远程入口地址,然后用异步组件的方式加载即可。
// 子应用(提供方)的配置
new ModuleFederationPlugin({
name: 'remoteApp',
filename: 'remoteEntry.js',
exposes: {
'./Button': './src/components/Button'
},
shared: {
react: { singleton: true },
'react-dom': { singleton: true }
}
})
// 主应用(消费方)的配置
new ModuleFederationPlugin({
name: 'hostApp',
remotes: {
remoteApp: 'remoteApp@https://cdn.bbccb.com/remote/remoteEntry.js'
},
shared: {
react: { singleton: true },
'react-dom': { singleton: true }
}
})消费方在代码里直接 import('remoteApp/Button') 就能拿到远程组件,体验上和本地模块几乎无差别。这套机制现在已经成为不少微前端方案(比如 Module Federation 在 qiankun 之外的另一条路线)的基础设施。不过要提醒的是,模块联邦对共享依赖的版本协商有要求,singleton 设为 true 时必须保证双方版本兼容,否则运行时会直接抛错,这一点在多团队协作时要提前约定好版本范围。
Tree Shaking 与构建产物优化
Webpack 5 的 Tree Shaking 能力有了实质性的增强,其中最实用的是嵌套的 export 无用代码消除和公共模块合并。以前从 lodash-es 这类库中导入单个函数,打包产物可能仍然带着整棵依赖树的一部分;现在编译器能分析更深层的导出结构,把没用的部分裁剪得更干净。
同时新增的 splitChunks 改进允许把多个 chunk 中重复的模块提取到共享 chunk 中,配合 usedExports 和 sideEffects 字段使用效果更佳。在 package.json 中声明 "sideEffects": false 之后,构建器可以放心地删除未被引用的模块,这一点对于维护组件库的同学尤其重要。
{
"name": "my-ui-lib",
"version": "1.0.0",
"sideEffects": false,
"main": "dist/index.js",
"module": "dist/index.esm.js"
}另外,产物层面还引入了对 Asset Modules 的原生支持,也就是用 asset/resource、asset/inline、asset/source 和 asset 四种类型替代过去的 file-loader、url-loader、raw-loader。这样一来,处理图片、字体等资源不再需要额外安装 loader,配置体积和维护成本都降下来了。
module.exports = {
module: {
rules: [
{
test: /\.(png|jpe?g|gif|svg)$/i,
type: 'asset',
parser: {
dataUrlCondition: {
// 小于 8kb 的图片转 base64 内联
maxSize: 8 * 1024
}
}
}
]
}
};从 Webpack 4 迁移的注意事项
升级到 Eerie Universe 并不是改个版本号那么简单。最大的破坏性变更是官方移除了对 Node.js 核心模块的自动 Polyfill,以前 process、path、buffer 这些模块在浏览器代码里可以直接引用,Webpack 5 会在编译时抛出错误提示。解决办法要么是手动安装对应的 polyfill 包并配置 resolve.fallback,要么是排查代码把对 Node API 的依赖去掉。很多老项目升级后构建直接爆红,基本都是这个原因。
其次是 Node.js 版本要求提升到了 10.13 以上,部分插件的旧版本不再兼容,比如 copy-webpack-plugin、html-webpack-plugin 都需要升到适配 Webpack 5 的大版本。命令行方面,webpack-cli 也要同步升级,旧的 webpack-dev-server 配置项也有变化,比如 contentBase 改成了 static.directory。建议迁移时先开启缓存观察构建速度,再逐个处理编译报错,最后用构建分析工具对比产物体积,确认 Tree Shaking 和 splitChunks 的收益符合预期。整体来看,尽管迁移有一定成本,但构建速度和产物体积的改善绝对值得投入。
Webpack 5Eerie Universe模块联邦修改时间:2026-09-13 22:21:52