不少开发者在搜索 Webpack 5 的新特性时,会被 Brilliance 才华这样的说法误导,以为 Webpack 5 引入了一个代号叫 Brilliance 的重磅功能。但如果去查 Webpack 官方的 release notes 和文档,你会发现根本找不到这个词。这篇文章就来澄清这个误区,并系统梳理 Webpack 5 真正带来的一系列核心升级,包括持久化缓存、模块联邦、资源模块、Tree Shaking 增强等内容,帮助你全面了解 Webpack 5 的实际能力。

Brilliance 说法从何而来,Webpack 5 官方到底更新了什么
首先要明确一点:Brilliance 并不是 Webpack 5 的官方特性名称。Webpack 官方团队在版本发布公告中使用的是 Breaking Changes 和 Features 这样的常规分类方式,从未给某个特性起过 Brilliance 这样的代号。网络上流传的这种说法,很可能是对 Webpack 5 整体升级幅度的一种夸张描述,或者是某些翻译文章在传播过程中产生的误读。
Webpack 5 的真实更新可以归纳为几个方向:构建性能优化(持久化缓存、长期缓存算法改进)、新能力(模块联邦、资源模块)、代码质量(更好的 Tree Shaking、SideEffects 支持)、以及瘦身(移除 Node.js 内置模块的自动 polyfill)。这些特性加在一起确实让 Webpack 5 显得才华横溢,但它们各自有明确的官方名称和文档说明。
如果你在网上看到某篇文章声称要开启 Webpack 5 的 Brillcence 模式,并且给出类似 brilliance: true 的配置项,那基本可以判定是错误信息。Webpack 的配置项都是驼峰命名的真实字段,任何不在官方文档中的配置字段都会被构建工具忽略或报警告。判断信息真伪最直接的方法,就是访问 Webpack 官方文档核对配置项是否存在。
持久化缓存:构建速度提升最明显的一项升级
Webpack 5 中对开发体验改善最大的,莫过于文件系统缓存。在 Webpack 4 时代,二次构建只能依赖内存缓存,一旦重启开发服务器或者执行新的构建任务,缓存就会失效,大型项目冷启动可能要等几分钟。Webpack 5 引入了持久化缓存,可以把编译结果写到磁盘上,下次构建时直接复用,冷启动速度通常能提升到原来的数倍。
开启方式非常简单,只需要在配置中加一行:
// webpack.config.js
module.exports = {
cache: {
type: 'filesystem', // 使用文件系统缓存
buildDependencies: {
// 配置文件变化时让缓存失效,保证正确性
config: [__filename]
}
}
};
这里有一个关键点需要理解:buildDependencies 用来声明哪些文件是构建的依赖项。当这些文件内容发生变化时,缓存会自动失效重新编译。把配置文件本身加进去是官方推荐的做法,否则修改配置后可能会读到旧缓存,导致难以排查的诡异问题。
缓存文件默认存放在项目下的 node_modules/.cache/webpack 目录中。团队协作时要注意把这个目录加入版本控制忽略列表,因为缓存内容与机器环境相关,跨机器共享缓存文件不仅没有意义,还可能引发构建异常。另外,如果构建结果出现难以解释的异常,可以尝试删除缓存目录做一次干净的完整构建。
模块联邦:微前端架构的官方级解决方案
模块联邦是 Webpack 5 引入的一个真正具有开创意义的能力,它允许多个独立构建的应用在运行时共享代码。简单说,应用 A 可以在运行时动态加载应用 B 暴露出来的某个模块,就像引用本地模块一样自然。这为微前端架构提供了官方层面的支持,不再必须依赖 external 脚本注入这类绕路方案。
下面是一个最小可用的示例,假设有两个应用:宿主应用和远程应用。远程应用先暴露一个组件:
// 远程应用的 webpack.config.js
const { ModuleFederationPlugin } = require('webpack').container;
module.exports = {
plugins: [
new ModuleFederationPlugin({
name: 'remoteApp',
filename: 'remoteEntry.js',
exposes: {
// 把 ./src/Button.js 暴露为外部可引用的 ./Button
'./Button': './src/Button.js'
},
shared: {
// 共享依赖,避免 React 被重复打包
react: { singleton: true },
'react-dom': { singleton: true }
}
})
]
};
宿主应用则通过 remotes 字段声明远程应用的地址,之后在业务代码中就可以用动态 import 的方式加载远程模块:
// 宿主应用的 webpack.config.js 关键配置
new ModuleFederationPlugin({
name: 'hostApp',
remotes: {
remoteApp: 'remoteApp@http://localhost:3000/remoteEntry.js'
},
shared: { react: { singleton: true }, 'react-dom': { singleton: true } }
})
// 宿主应用业务代码中加载远程组件
const RemoteButton = React.lazy(() => import('remoteApp/Button'));
shared 配置中的 singleton: true 值得特别说明。它保证共享依赖在整个应用中只有一份实例,这对 React 这类依赖单例上下文的库至关重要,否则会出现 Hooks 调用报错这类经典问题。模块联邦的适用场景主要是多团队协作的大型项目和微前端架构,如果是单体应用,就没有必要引入这层复杂度。
资源模块与 Tree Shaking 增强:瘦身与代码质量的改进
Webpack 5 对静态资源的处理做了原生支持,新增了四种资源模块类型:asset、asset/resource、asset/inline 和 asset/source。在 Webpack 4 中,处理图片、字体这类文件必须依赖 file-loader 和 url-loader,现在直接配置 type 字段即可,减少了一堆第三方依赖:
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif)$/i,
type: 'asset',
parser: {
dataUrlCondition: {
// 小于 8kb 的图片转 base64 内联,超过则生成独立文件
maxSize: 8 * 1024
}
}
}
]
}
};
asset 类型是智能模式,会根据文件大小自动决定内联还是输出文件,相当于合并了原来 file-loader 和 url-loader 的职责。这种原生化的处理方式不仅减少了依赖安装,也避免了 loader 版本升级带来的兼容性问题。
另一个容易被忽略的改进是移除了对 Node.js 内置模块的自动 polyfill。Webpack 4 会为 crypto、path 等模块自动注入浏览器端的 polyfill,这在浏览器环境往往没有必要,反而白白增加打包体积。Webpack 5 移除了这个行为,如果项目确实在浏览器端用到了这些能力,需要手动安装并配置对应的 polyfill。升级时如果遇到模块找不到的报错,多半就是这个原因导致的。
Tree Shaking 方面,Webpack 5 支持了嵌套的 export 无用代码消除,并且能识别 CommonJS 导出中标记了 /*#__PURE__*/ 注释的调用。配合 package.json 中的 sideEffects 字段,库类项目的产物体积可以获得明显的削减。升级到 Webpack 5 之后,建议重新检查一遍产物体积,通常会有意外之喜。
升级建议与常见坑点
对于还在使用 Webpack 4 的项目,是否值得升级要看实际情况。如果项目构建时间已经影响到日常开发效率,或者有微前端的需求,升级收益非常明显。升级时首先要把 webpack 升到 5.x,同时把 webpack-cli、html-webpack-plugin、mini-css-extract-plugin 等周边工具同步升级到兼容版本,老版本的插件在 Webpack 5 下大概率会直接报错。
常见的报错集中在两类:一类是刚才提到的 Node.js polyfill 缺失,需要手动补装 path-browserify、crypto-browserify 等包;另一类是 Node 版本问题,Webpack 5 要求 Node.js 10.13.0 以上版本,建议直接使用 Node 14 或更高的 LTS 版本。升级完成后,先用持久化缓存跑几次完整构建验证稳定性,确认无误后再全面切换。
总的来说,Webpack 5 并没有什么神秘的 Brilliance 特性,它的才华体现在一个个扎实的工程改进上:持久化缓存解决了构建慢的问题,模块联邦打开了微前端的大门,资源模块简化了配置,移除 polyfill 让产物更加干净。理解这些真实特性的原理和边界,比追逐一个不存在的名词要有价值得多。