如果每次构建输出的文件名称是一样的,会给在客户端做长缓存带来很大的麻烦。因此,我们需要在输出的文件名中添加一些 hash 值,使得每次构建输出的文件名称是不一样的。
从 Webpack 5 开始,Webpack 开始使用固定的方式来决定输出的文件名,我们可以通过
optimization.moduleIds
和optimization.chunkIds
这两个字段进行控制。
占位符(placeholder)
Webpack 提供了一些占位符:
[id]
返回 chunk id[path]
返回文件路径[name]
返回文件名[ext]
返回文件扩展名[fullhash]
返回本次构建的 hash,如果本次构建过程中有任何一部分发生变化,这个 hash 也会变化[chunkhash]
返回每一个 entry chunk 的 hash。Webpack 配置定义的每一个 entry 都有一个自己的 hash,当 entry 中任何一部分发生变化,这个 hash 也会发生变化。[chunkhash]
比[fullhash]
粒度更细一点。[contenthash]
返回模块内容的 hash。从 Webpack 5 开始,这个 hash 值被默认使用在生产模式构建中。
假设有如下配置:
const config = {
output: {
path: PATHS.build,
filename: '[name].[contenthash].js',
},
};
2
3
4
5
6
Webpack 构建输出的文件名为:
main.d587bbd6e38337f5accd.js
vendor.dc746a5db4ed650296e1.js
2
此时,如果文件内容发生变化,则 [contenthash]
也会相应的变化,此时,浏览器缓存就会失效,浏览器就会重新发起一个请求来加载变化了的文件。即,如果仅仅只要 main.js
发生了变化,那么浏览器只会重新请求加载 main.js
。
我们还可以将 hash 值加载请求参数中,比如 main.js?d587bbd6e38337f5accd
, 这样的话,输出文件名不变,通过查询参数的变化来使缓存失效。
使用占位符
webpack.config.js
const productionConfig = merge([
{
output: {
chunkFilename: "[name].[contenthash].js",
filename: "[name].[contenthash].js",
assetModuleFilename: "[name].[contenthash][ext][query]",
},
},
...
]);
2
3
4
5
6
7
8
9
10
同时,我们还要给 css 也加上 hash。
webpack.parts.js
exports.extractCSS = ({ options = {}, loaders = [] } = {}) => {
return {
...
plugins: [
new MiniCssExtractPlugin({
// filename: "[name].css",
filename: "[name].[contenthash].css",
}),
],
};
};
2
3
4
5
6
7
8
9
10
11
执行 npm run build
,可以看到输出如下:
⬡ webpack: Build Finished
⬡ webpack: assets by path *.js 129 KiB
asset 935.a25ff4285adcf5d835fd.js 126 KiB [emitted] [immutable] [minimized] (id hint: vendors) 2 related assets
asset main.fdae79f138a0e0cd6a30.js 3.38 KiB [emitted] [immutable] [minimized] (name: main) 1 related asset
asset 958.1752e720e564a63a9d5f.js 204 bytes [emitted] [immutable] [minimized] 1 related asset
asset main.dd02bdb46b234aa6a450.css 1.37 KiB [emitted] [immutable] [minimized] (name: main)
asset index.html 322 bytes [emitted]
Entrypoint main 131 KiB (182 KiB) = 935.a25ff4285adcf5d835fd.js 126 KiB main.dd02bdb46b234aa6a450.css 1.37 KiB main.fdae79f138a0e0cd6a30.js 3.38 KiB 2 auxiliary assets
runtime modules 7.92 KiB 10 modules
orphan modules 465 bytes [orphan] 2 modules
code generated modules 133 KiB (javascript) 4.18 MiB (css/mini-extract) [code generated]
modules by path ./node_modules/ 133 KiB
modules by path ./node_modules/react/ 6.48 KiB 2 modules
modules by path ./node_modules/react-dom/ 119 KiB 2 modules
modules by path ./node_modules/scheduler/ 4.91 KiB
./node_modules/scheduler/index.js 198 bytes [built] [code generated]
./node_modules/scheduler/cjs/scheduler.production.min.js 4.72 KiB [built] [code generated]
./node_modules/object-assign/index.js 2.06 KiB [built] [code generated]
modules by path ./src/ 633 bytes (javascript) 4.18 MiB (css/mini-extract)
./src/index.js + 2 modules 600 bytes [built] [code generated]
css ./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[3]!./src/main.css 4.18 MiB [code generated]
./src/lazy.js 33 bytes [built] [code generated]
webpack 5.11.1 compiled successfully in 18695 ms
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
现在尝试编辑 main.css
,可以发现构建输出的文件名发生了变化。
总结
Webpack 提供的占位符可以帮助我们给输出文件名添加额外信息。
在这些占位符中,最有价值的是 [name]
, [contenthash]
和 [ext]
。 [contenthash]
基于文件内容生成 hash 值。
如果要导出 css 文件,即用了 MiniCssExtractPlugin
,那么也需要在 css 文件名中使用 [contenthash]
。
关注微信公众号,获取最新推送~
加微信,深入交流~