新版本构建成功、服务也正常,用户却在切换某个菜单时遇到加载失败。重新打开网站又好了。这类现象容易被当成偶发网络问题,实际可能是新旧资源版本错位。
用户浏览器里的入口还是旧的
懒加载模块只有在访问相关页面时才下载。用户已经打开旧版页面,发布时服务器替换了构建产物,旧入口还记着之前的 chunk 文件名。
等用户后来点击菜单,浏览器才请求旧文件;服务器上已经没有它,就会出现动态模块加载错误。构建成功证明了新资源能生成,无法证明老页面还能找到自己的资源。
恢复逻辑必须限制次数
项目给 Vite 的 preloadError 增加了恢复处理:识别失败签名,记录当前会话已处理的错误,并使用带一次性参数的地址重新加载入口。恢复后的地址会清掉该参数。
关键不是“遇错就刷新”,而是给刷新加边界。同一错误持续出现时,不能让用户进入反复重载;存储不可用的环境也要考虑退化行为。
客户端恢复只是其中一层
部署说明同步补充了入口 HTML 与静态资源缓存策略。入口应及时拿到新版本,带内容哈希的资源则适合长期缓存;部署时保留旧资源,还能进一步减小版本切换窗口。
缓存策略、产物保留和客户端恢复分别负责不同环节,不能只靠一段刷新代码解决所有发布问题。
留下的检查点
上线验收除了重新打开页面,还应该保留一个旧页面:发布新版本之后,再点击此前没有打开的路由,观察懒加载失败与恢复行为。
这件事让我把浏览器中的存量会话也看作发布对象。服务端已经切到新版本,用户并不一定同步完成切换。
记录对应 2026-07-20 的提交 6bb9a22f0,包含恢复服务、测试和部署缓存规范。