远程组件发布后,如何避免脚本与样式版本错配
从独立交付的组件库出发,讨论资源版本、发布顺序和旧页面存活期,让一次更新对应一组完整产物,而不是分别覆盖几个文件。
延伸分析 · 从项目场景展开的原理与方案讨论。
- 组件库
- 静态资源
- 版本管理
- 缓存
关联项目:跨系统共享业务组件库。独立构建已经存在;下面分析进一步采用远程资源加载时的发布一致性,不代表当前部署具备文中所有机制。
单个请求成功,组合仍可能失败
组件的新脚本依赖了新样式,宿主却从缓存中读取旧 CSS;或者入口脚本已更新,它引用的分块还没上传完成。所有文件单独看都合理,组合到一个页面却不是同一版本。
真正需要发布的是一份能够共同运行的资源集合:入口、样式、动态分块及必要的宿主兼容约定。
让版本对应不可变资源
一种可分析的方案是:每个版本拥有独立资源路径或内容哈希,清单把入口、样式和依赖资源绑定到同一个版本。页面解析一次清单后固定使用这一版,避免不同步骤反复读取一个会变化的“最新版”地址。
release A → entry A + styles A + chunks A
release B → entry B + styles B + chunks B
即便使用清单,也要确认 CSS 内的字体、图片等间接资源能够正确解析。清单只列了入口,不代表资源闭包已经完整。
先准备产物,再切换入口
发布过程可以先上传新版本全部资源并检查可访问性,再切换清单或版本指针。切换之后保留旧版本,让已经打开的页面仍可加载它依赖的分块。
Vite 的加载错误说明讨论了更新后旧页面请求已被删除分块的情况。这里借用这个失败模型分析远程组件,并不依赖特定版本的错误事件 API。
旧资源保留多久,需要结合页面最长会话、缓存策略和回滚窗口确定。没有保留期承诺,就不能声称老页面永远无感更新。
回滚也要成组进行
回滚应切回完整版本,而不是只替换入口 JS。如果宿主和组件之间的 Props、事件或数据格式发生了不兼容变化,静态资源回滚也未必能恢复服务,需要提前定义兼容范围。
组件加载失败时,可以给出可重试的状态或保留宿主其他功能。自动刷新整个页面之前,应考虑用户还有没有未保存内容。
验证旧页面跨越一次发布
先打开 A 版本但不触发某个懒加载功能,再发布 B,随后在旧页面中打开该功能。继续验证脚本新而 CSS 旧、部分文件上传失败、清单缓存未更新以及整体回滚。
这些检查比“发布后新开一个页面正常”更接近真实使用。发布一致性关心的是一个页面生命周期中的整套资源,而不是某一刻单个文件的状态码。