背景
最近项目更新频繁,每次一更新客户都说还跟之前的一样。一查原因是因为客户没有清空浏览器的缓存。所以为了方便客户看到最新版本,开始调研再发布新版本后自动清理缓存。
方案
每次打包后的js和css都加上hash值后缀。当文件发生改变时,hash值也改变。这样就不会走缓存
举个例子
vue.config.js
const path = require("path"); // 获取当前的时间戳
module.exports = {
publicPath: "./",
filenameHashing: false,
configureWebpack: {
output: {
filename: `js/js[name].[hash].js`, //hash可替换为contenthash 下面同理
chunkFilename: `js/chunk.[id].[hash].js`,
}
},
// css: { 这个可要可不要
// extract: {
// filename: `css/[name].[hash].css`,
// chunkFilename: `css/chunk.[id].[hash].css`,
// }
// }
};
上述配置中,我们使用了[hash]占位符来为文件名添加一个基于内容的哈希值。这样,每次发布新版本时,文件名会随之改变,从而强制浏览器重新下载和缓存新的文件。
注意,这种方法只适用于JavaScript文件和CSS文件。如果你想清除其他类型的缓存,如图片、字体等,可以使用workbox-webpack-plugin插件来生成Service Worker,并在其中添加缓存管理逻辑。你可以在vue.config.js文件中添加以下配置来使用该插件:
const { GenerateSW } = require('workbox-webpack-plugin');
module.exports = {
// ...其他配置
configureWebpack: {
plugins: [
new GenerateSW({
// ...缓存管理逻辑
})
]
}
}
使用workbox-webpack-plugin需要一定的Service Worker基础知识,如果你不熟悉该插件的使用方法,建议先查阅相关文档。
相关说明
contenthash 和 hash有什么区别?
hash和contenthash都是Webpack中用于生成唯一哈希值的占位符,它们的主要区别在于生成哈希的依据不同。
hash是根据整个项目的构建情况生成的哈希值,也就是说,只要项目中任意一个文件发生变化,生成的哈希值就会发生改变。这意味着,如果你在项目中有多个入口文件或者多个chunk,那么它们都会使用同一个hash占位符,生成的哈希值也会相同。因此,hash通常用于项目的整体构建过程中,用于区分不同版本的构建结果。
contenthash则是根据文件的内容生成的哈希值,也就是说,只要文件内容发生变化,生成的哈希值就会发生改变。这意味着,如果你在项目中使用了contenthash占位符,那么每个文件都会生成独立的哈希值,不受其他文件的影响。因此,contenthash通常用于文件级别的缓存控制中,用于强制浏览器重新下载和缓存新的文件,而不是重复使用旧的缓存文件。
在实际开发中,建议根据具体需求选择合适的哈希占位符。如果你需要在整个项目构建过程中保持哈希值的一致性,可以使用hash占位符;如果你需要对每个文件进行独立的缓存控制,可以使用contenthash占位符。在Vue项目中,通常使用[contenthash]占位符来对JavaScript和CSS文件进行独立的缓存控制,从而实现自动清除缓存的效果。
图片资源如何打包添加hash值
module.exports = {
output: {
publicPath: '/assets/'
},
module: {
rules: [
{
test: /\.(png|jpe?g|gif|svg)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8192,
name: '[name].[hash:8].[ext]',
outputPath: 'assets/'
}
}
]
}
]
}
};
在这个例子中,url-loader将所有小于等于8KB的图片资源转换成Base64编码的字符串,并将其嵌入到JavaScript或CSS文件中,而大于8KB的图片资源则会被输出到/assets目录中,并且其文件名包含哈希值,以避免浏览器缓存问题。最后,output.publicPath指定了图片资源的URL路径为/assets/。
长风破浪会有时,直挂云帆济沧海