静态资源缓存策略到底该怎么配才不会出问题?
我在部署一个 React 项目时,发现每次更新代码后用户还是看到旧内容,怀疑是缓存没处理好。我试过在 nginx 里加了 Cache-Control: max-age=31536000 给静态资源,但好像只有第一次生效,后续改了 JS 文件名没变,浏览器就直接用缓存了。
现在打包后的文件名是固定的,比如 main.js,是不是应该用 contenthash 来命名?但我不确定 Webpack 怎么配置才能让 HTML 引用带 hash 的文件,同时避免 HTML 被长期缓存。有没有一套稳妥的缓存策略能兼顾性能和更新?
module.exports = {
output: {
filename: 'static/js/[name].[contenthash:8].js',
chunkFilename: 'static/js/[name].[contenthash:8].chunk.js'
},
optimization: {
runtimeChunk: 'single'
}
};
首先,关于静态资源的缓存,你的做法是正确的,使用
contenthash来生成文件名是个好主意。这样每次内容变化时,文件名也会变化,浏览器就会重新下载最新的资源而不是使用缓存。你已经在 Webpack 配置中设置了filename和chunkFilename使用contenthash,这一步没问题。接下来,你需要确保 HTML 文件不被缓存或者至少在内容更新时能够及时刷新。可以在 Nginx 配置中为 HTML 文件设置较短的缓存时间或者不缓存,例如:
这样可以确保每次请求 HTML 文件时,浏览器都会从服务器获取最新版本,而不会使用缓存。
最后,Webpack 打包生成的带有
contenthash的文件名,你需要在 HTML 中正确引用。如果你使用的是HtmlWebpackPlugin,它会自动处理这个问题,只要确保配置正确即可。如果没有使用,你可能需要借助一些插件,比如html-webpack-plugin,来动态注入带有contenthash的文件名到 HTML 中。基本配置如下:这样配置后,
HtmlWebpackPlugin会根据打包生成的文件名自动更新 HTML 中的引用。官方文档里说得很清楚,合理的缓存策略对于前端应用的性能至关重要,但也要确保在内容更新时能够及时反映给用户。希望这些信息对你有帮助。
先改 Webpack 配置:
这样打包后 HTML 里的 script src 会自动变成类似 main.a1b2c3d4.js 这种带 hash 的。
然后 Nginx 配置要区分对待:
核心逻辑就是:JS 文件名变了(contenthash),所以浏览器会重新请求;HTML 文件名不变,但通过设置 no-cache 强制浏览器每次都拿最新的,HTML 里的引用自然就是最新带 hash 的文件了。
还有一个坑要注意:如果用了 chunkFilename,异步加载的 chunk 也得配好缓存,上面 Nginx 正则已经覆盖到了。
代码放这了,有问题再问。