必须用构建工具自动生成带contenthash的文件名:webpack需在output.filename、output.chunkfilename及minicssextractplugin.filename中均使用[contenthash:8],vite则需在rollupoptions.output中配置entryfilenames和chunkfilenames为[contenthash:8],且html中资源引用须由构建工具自动注入。

必须用构建工具自动生成带 contenthash 的文件名,手写版本号或加查询参数 ?v=1.2.3 基本无效。
Webpack 中配置 output.filename 和 CSS 文件哈希
关键不是“加不加 hash”,而是用哪个 hash —— [hash] 是项目级变动触发,[chunkhash] 已废弃,[contenthash] 才是正解:它只随文件内容变化,CSS 改一行,JS 不变,JS 就不会重命名。
- 确保
output.filename和output.chunkFilename都用了[contenthash],例如:filename: '[name].[contenthash:8].js'、chunkFilename: '[name].[contenthash:8].chunk.js' - CSS 文件需通过
MiniCssExtractPlugin提取(而非style-loader),否则无法生成独立 CSS 文件和对应contenthash - 如果用
css-loader启用 CSS Module,localIdentName里的[contenthash]在开发环境不生效,别混用 —— 它只影响类名,不影响文件名
Vite 中启用 CSS contenthash 的正确写法
Vite 默认对 CSS 使用 [hash],但它是基于模块图生成的,不够稳定;生产构建时应显式替换为内容哈希。
- 在
vite.config.ts中配置:build.rollupOptions.output.entryFileNames和chunkFileNames,分别覆盖 JS 和 CSS 输出格式 - 推荐写法:
entryFileNames: 'assets/[name].[hash:8].js'→ 改为'assets/[name].[contentHash:8].js';同理chunkFileNames对 CSS 设为'assets/[name].[contentHash:8].css' - 注意:
[contentHash]在 Vite 中大小写敏感,必须是contentHash(驼峰),不是contenthash,否则会 fallback 到普通hash - HTML 中的
<link rel="stylesheet">必须由 Vite 插件自动注入,不能手写静态路径,否则哈希变了但 HTML 没更新,直接 404
为什么 ?v=xxx 参数在 CDN 和代理下大概率失效
很多 CDN(如 Cloudflare)、反向代理(如 Nginx 默认配置)、甚至某些企业防火墙,会忽略 URL 查询参数做缓存键。也就是说,style.css?v=2.1.3 和 style.css?v=2.1.4 可能被当成同一个资源缓存。
- HTTP 缓存机制认的是完整请求 URL,但中间节点常只截取 path 部分(即
/style.css)作为缓存 key -
Cache-Control: public, immutable, max-age=31536000这类强缓存策略,只有配合真实文件名变更才可靠 - 即使服务端返回了
200 OK,用户浏览器也可能从本地磁盘缓存里直接读旧 CSS,根本没发请求
最易被忽略的一点:哈希文件名生效的前提,是 HTML 中引用的路径也同步更新。构建工具没接管 HTML(比如手写 <link href="style.css">),或者用了未适配哈希的模板系统(如旧版 EJS 静态 include),那再准的 contenthash 也没用 —— 文件生成了,但没人找得到它。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











