浏览器可以使用缓存技术来降低网页流量,从而使网站加载速度更快。
但是我们在部署新版本时如果不更改资源名称,浏览器很可能认为资源没有被更新从而使用缓存版本。
我们可以通过配置,确保webpack编译生成的文件能被浏览器缓存,而文件内容发生变化后可以请求到新的文件。
1、可替换模板字符串(substitution)
利用[contenthash]
可以根据资源内容创建出唯一的hash。当资源发生变化时,文件名称就会发生变化。
module.exports = {
output: {
filename: "[name].[contenthash].js",
},
}
2、提取引导模板(runtime)
使用optimization.runtimeChunk将runtime代码拆分出一个独立的chunk,将其设置为single
来为所有的chunk创建一个runtime bundle。
用于webpack优化。
optimization: {
runtimeChunk: "single",
}
3、提取第三方库
一些第三方库很少修改,可以将第三方库提取到vendor
chunk中。
这样可以利用浏览器的偿还村机制,命中缓存来消除请求,并减少向server获取资源。
通过设置splitChunks.cacheGroups进行设置。
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
}
}
4、模块标识符
上面的代码中我们已经将chunk分为了app.[hash].js、runtime.[hash].js、vendor.[hash].js。其中vendor chunk主要是第三方库,我们希望能够利用浏览器缓存机制缓存起来提升页面的加载速度。但是目前每次打包后vendor.[hash].js的名称都会发生变化。
- app: 当自身内容修改后会发生变化
- runtime(manifest) :当新增bundle时发生变化,比如在entry中新增入口,或者使用动态引入等。只要bundle出现修改就会发生变化。
- vendor: 随自身
module.id
的变化而变化。webpack打包时module.id使用自增长数字,当有新增|删除module模块时,module.id就会发生变化。 - 我们在这里不希望module.id发生变化,使用webpack提供的
HashedModuleIdsPlugin
,用于生产环境构建。
const webpack = require("webpack");
module.exports = {
plugins: [
new webpack.HashedModuleIdsPlugin()
]
}
这里是对module.id进行固定。如果对chunk.id固定需要自定义插件,参考:https://zhuanlan.zhihu.com/p/34110535