前端阅读 05月30日 23:22
Module Federation 生产环境部署要注意哪些坑?
Module Federation 的生产部署比普通前端应用多一个关键变量:Host 和 Remote 不一定同时发布。这个能力带来了独立交付,也带来了缓存、版本、回滚和跨域问题。很多线上事故不是代码逻辑错,而是 Host 加载到了旧的 remoteEntry、Remote 静态资源路径不对,或者 CDN 把本该及时更新的入口文件缓存住了。稳妥的部署策略是把 remoteEntry 当成运行时入口,而不是普通静态资源随便缓存。Remote 的 JS、CSS chunk 可以带 hash 长缓存,但 remoteEntry.js 建议短缓存或 no-cache,并通过版本化目录保留历史构建。Host 不要硬编码唯一地址,最好从环境变量或配置中心读取当前可用版本,这样 Remote 回滚时不必重新构建 Host。独立部署的价值,必须靠版本管理和回滚机制兑现。location /remoteEntry.js { add_header Cache-Control "no-cache, no-store, must-revalidate"; try_files $uri =404;}location /assets/ { add_header Cache-Control "public, max-age=31536000, immutable";}new ModuleFederationPlugin({ name: 'host', remotes: { order: `order@${process.env.ORDER_REMOTE_URL}/remoteEntry.js` }, shared: { react: { singleton: true, requiredVersion: '^18.2.0' }, 'react-dom': { singleton: true, requiredVersion: '^18.2.0' } }})Nginx 配置解决缓存边界,Webpack 配置解决运行时地址。这里的取舍是:remoteEntry 不缓存会多一次网络请求,但换来的是发布和回滚可控;chunk 长缓存能降低流量,但前提是文件名带 hash 且旧版本不会立刻删除。Remote 构建产物最好保留最近几版,避免 Host 或用户浏览器还引用旧 chunk 时出现 404。追问remoteEntry.js 应该缓存多久?生产环境通常不建议长缓存 remoteEntry,因为它决定 Host 当前会加载哪些 chunk 和暴露模块。可以使用 no-cache,让浏览器每次校验;如果流量很大,也可以设置很短的 max-age,并配合版本化 URL。取舍是缓存越短,请求越多;缓存越长,发布和回滚越不可控。真正适合长缓存的是带内容 hash 的 chunk 文件,而不是 remoteEntry。Host 和 Remote 谁先部署比较安全?如果是兼容性变更,通常先部署 Remote,再让 Host 使用新能力;如果是破坏性变更,必须先让 Remote 同时兼容新旧契约,再逐步升级 Host。不要让 Host 先调用一个尚未上线的暴露模块,也不要让 Remote 删除旧模块后仍有旧 Host 在访问。边界规则很简单:公开契约至少保留一个灰度周期。踩坑最多的是“本团队已经发版了”,但另一个团队的 Host 还在旧版本。静态资源 publicPath 配错会有什么表现?最常见表现是 remoteEntry 能加载,真正进入页面时 chunk、CSS 或字体 404。因为 remoteEntry 只负责登记模块,后续异步 chunk 还要根据 publicPath 拼地址。可以使用 publicPath: 'auto',也可以在不同环境明确注入 CDN 域名。多租户或私有化部署时尤其要小心,硬编码生产 CDN 会让客户环境直接白屏。跨域和安全头怎么配置?Host 加载 Remote 本质上是跨源脚本执行,所以 Remote 域名需要允许正确的 CORS 和静态资源访问。脚本加载通常不需要像接口那样复杂的凭证跨域,但 Source Map、字体、图片和接口请求会受响应头影响。安全上要限制 Remote 来源,不要让配置中心返回任意域名。企业环境还要配合 CSP,把可信 Remote 域名加入 script-src,否则浏览器会直接拦截。Remote 发布失败时怎么降级?Host 应该给每个远程模块包一层错误边界和加载超时处理。入口加载失败时,可以隐藏菜单、展示轻量错误页,或者回退到上一版 Remote 地址。取舍是自动回滚需要更完善的健康检查,否则可能因为一次网络抖动频繁切换版本。至少要把 remoteEntry 加载失败、chunk 404、初始化异常打到监控里,并带上 Remote 名称和版本号。生产部署的核心不是把几个应用放到 CDN 上,而是让 Host 和 Remote 在不同发布节奏下仍然可预测。缓存边界、版本保留、契约兼容、跨域安全和监控回滚都到位,Module Federation 的独立部署才算真正落地。