资源版本冲突的核心解法是静态资源用contenthash命名、HTML构建时生成并原子发布;仅加?v=xxx无效因CDN等忽略查询参数,必须将哈希嵌入文件名如main.a1b2c3d4.js,且HTML禁用强缓存、静态资源设长期缓存。

资源版本冲突不是“HTML没刷新”这么简单,而是新 HTML 引用了旧 JS/CSS,或多个服务器节点返回不一致的哈希路径——直接导致 404 或脚本执行报错。核心解法是:静态资源必须用 contenthash 写进文件名,HTML 必须构建时生成、原子发布,不能运行时拼接。
为什么只加 ?v=xxx 查询参数会失效
CDN、浏览器、代理常忽略 URL 查询参数做缓存判断。比如你配了 html-webpack-plugin 的 hash: true,结果生成 main.js?v=a1b2c3,但服务器上还是叫 main.js,CDN 缓存了这个路径,下次请求仍返回旧内容;而真正有效的 contenthash 必须出现在文件名里,如 main.a1b2c3d4.js,这样路径一变,缓存就自然失效。
-
output.filename必须含[contenthash],例如'js/[name].[contenthash:8].js' -
MiniCssExtractPlugin.filename同理,不能只靠 CSS 文件内联或style-loader -
html-webpack-plugin的hash: true应关闭,改用templateParameters把真实文件名传入模板 - 模板需支持插值(如
.ejs),否则不会展开
多实例部署时 HTML 被“动态渲染”就必然出问题
常见错误是后端模板引擎(如 Thymeleaf、EJS)在每次请求时读取本地 manifest.json 并渲染 <script></script> 标签。A 节点加载的是 v1.2.0 的 manifest,B 节点加载的是 v1.2.1 的,用户从 A 刷新到 B,HTML 里写的 app.x1y2z3.js 在 B 节点根本不存在。
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
- 所有 HTML 文件必须由构建阶段产出,和 JS/CSS/manifest.json 一起打包、原子发布
- 若必须后端渲染(如 SSR),
manifest.json需上传至共享存储(S3/MinIO),后端启动时加载一次并缓存,禁止每次请求都读盘 - 检查 CI/CD 流程:HTML + 静态资源 + manifest 是否走同一发布通道,中间状态不可被 CDN 缓存
Nginx 对 .html 的缓存配置极易锁死旧版
很多 Nginx 配置把 /index.html 当作静态资源,设了 Cache-Control: public, max-age=31536000,结果 HTML 永远不更新,哪怕 JS 已换名,用户也拉不到新 HTML 来引用它。
立即学习“前端免费学习笔记(深入)”;
- 对 HTML 路径禁用强缓存:
add_header Cache-Control "no-cache"; - 启用协商缓存:
etag on; if_modified_since exact;,让浏览器发If-None-Match请求校验 - 对带哈希的静态资源(
.js、.css等)设长期缓存:expires 1y; add_header Cache-Control "public, immutable"; - 别信
<meta http-equiv="Cache-Control">,现代浏览器基本忽略它对外部资源的控制
最易被忽略的一点:Service Worker 不是缓存治理主力,而是兜底手段。一旦你在 install 阶段 fetch manifest.json 再 cache.put(),就会引入严重时序问题——HTML 已执行,但 SW 还没完成预加载,脚本报错;或者 SW 更新了缓存,但 HTML 仍引用旧路径,造成 mismatch。真正的版本一致性,必须在构建和部署环节闭环。


















