构建与部署 · 收录于 2026-08-29 · 适用 2 工具 ✓ 实测验证

前端发布后偶发白屏(ChunkLoadError / 版本错位)

已验证 2026-08-29发布后偶发白屏 ChunkLoadError——版本错位:先上传新 dist 资源、最后才覆盖 index.html,旧资源保留至少一个发布周期。

快速修复

# 一键:发布顺序修正——先上资源、后切入口,旧资源保留至少一个发布周期
# 1) 先把新版本 dist/ 全部上传(含新 hash 资源) 2) 最后再上传/切换 index.html

发布脚本里把 index.html 的覆盖放到最后一步,并且上传时保留旧资源目录。

你会遇到什么

发布新版本后,部分用户白屏,刷新又偶尔恢复;控制台报 ChunkLoadError: Loading chunk N failed;动态 import 请求的带 hash 资源返回 404。你自己访问却是好的——因为你的缓存是新的。

本文路径:快速修复(30 秒一段命令)→ 一步步排查(可跳读)→ 原理与变体(症状/原因/证据)。赶时间直接跳到「快速修复」。

为什么会这样

版本错位:浏览器缓存的旧入口 HTML 仍引用旧版本 hash chunk,而服务器新发布已经删掉了旧资源。用户触发动态 import 时,旧 chunk 404 → 模块加载失败 → 整页白屏。

角色状态
用户浏览器缓存着旧版入口 HTML,指向旧 hash 资源
服务器已部署新版本,旧资源已删除
结果旧 chunk 404 → ChunkLoadError → 白屏

Vite 构建的 chunk 文件名带内容 hash(实测:feature-DP5yDwy7.js → feature-PcJGFbac.js),版本一变 hash 就变,新旧 HTML 引用的资源完全不同。

Vite 构建产物是「入口 HTML + 带内容 hash 的 chunk」:hash 由文件内容算出,内容变 hash 就变。浏览器先拿到入口 HTML,运行时再按 HTML 里的引用去加载 chunk——这是两步取用,中间隔着一段时间,而这段时间里服务器可能已经发布新版本并删除了旧 chunk。

用户浏览器缓存的旧 HTML 指向旧 hash,服务器已没有该资源 → 动态 import 404 → ChunkLoadError。

确定性推论:这不是代码 bug,是「客户端引用集」与「服务器资源集」的版本错位;修法三选一——部署时保留旧 chunk(不删 dist 旧文件/用带版本前缀的目录)、让入口 HTML 不缓存(Cache-Control: no-cache,chunk 仍可长缓存)、或升级时全量刷新(发布后提示刷新/自动 reload)。

判断依据:Network 面板里失败请求的 URL 带旧 hash,而服务器 dist 里没有同名文件。

一步步来

1. 发布顺序:先资源后入口 — 必做

hash 静态资源先上线,入口 HTML 最后切换。这样新旧入口都能找到自己的资源。

2. 旧资源保留过渡期 — 必做

至少保留一个发布周期的旧资源(连续发布时尤其重要),让还持有旧入口的用户平滑过渡。

3. nginx fallback 不能吞静态资源 404 — 必做

try_files 先匹配真实文件,再回退 index.html,不能无差别 fallback:

location / {
  try_files $uri $uri/ /index.html;   # 先真实文件,后回退
}

4. CDN 与 Service Worker 遵循同一套版本一致性规则 — 必做

CDN 缓存策略和 SW 更新逻辑都要按"资源先于入口"设计,别让缓存层放大版本错位。

怎么确认修好了

用旧版本入口模拟老用户访问(预期形态):

curl -H "Cache-Control: no-cache" http://你的域名/feature-PcJGFbac.js
→ HTTP 200(新 hash 资源在)
curl -I http://你的域名/index.html
→ HTTP 200,引用资源列表与线上资源一致

发布后新旧页面均 HTTP 200(实测:保留旧资源后新旧页面均 200);连续发布多轮不再出现 ChunkLoadError。

其它环境的表现

环境说明
单次发布先资源后入口即可解决
连续发布旧资源至少保留一个发布周期,否则上一轮用户仍会白屏
nginx SPA fallback先 try_files $uri 再回退,别吞静态资源 404
CDN / Service Worker与服务器同一套版本一致性规则
已白屏用户强刷或重新打开即可恢复(缓存刷新后入口变新)

症状

发布后部分用户白屏、刷新又偶尔恢复;控制台报 ChunkLoadError: Loading chunk N failed;动态 import 请求的带 hash 资源返回 404。

原因

版本错位:浏览器缓存的旧入口 HTML 仍引用旧版本 hash chunk,而新发布已删除旧资源 → 动态 import 404 → 模块加载失败 → 整页白屏。

解法

  1. 发布顺序:先资源后入口(hash 静态资源先上线,入口 HTML 最后切换)
  2. 旧资源保留过渡期(至少覆盖一个发布周期)
  3. nginx SPA fallback 不能吞静态资源 404(try_files 先匹配真实文件,再回退 index.html)
  4. CDN 与 Service Worker 遵循同一套版本一致性规则
验证证据
  • 本地实测(2026-08-29):vite 5.4.21 两次 build,chunk hash 变化(feature-DP5yDwy7.js → feature-PcJGFbac.js);服务器只部署 v2 资源时旧 chunk HTTP 404(复现);保留旧资源后新旧页面均 HTTP 200(解法成立)。
  • 实测复现日志(2026-08-29)

适用工具 (2)

本问题方案已挂到下列工具的方案页——从工具页也能回到这里,双向可达。

vite-deploynginx · 外部工具

成套方案 (组合包)

这个问题包含在下列成套安装方案中。

来源与证据

收录 验证 ✓ 实测验证适用 2 工具
方案含本地实测或来源可复核的解法;未实测项已在文中如实标注。

素材来源:https://juejin.cn/post/7678324462626471946

← 构建与部署 问题域 | 问题货架 | 遇到其它问题?去 问题空间 提交求助卡