Module Federation 中远程模块加载失败怎么办?
我在用 Webpack 5 的 Module Federation 搭微前端,主应用能正常启动,但加载远程子应用时一直报错“Container initialization failed”,控制台显示 404。
我确认子应用已经运行在 http://localhost:3001,而且在主应用的 webpack 配置里也正确声明了 remote:
remotes: {
app2: 'app2@http://localhost:3001/remoteEntry.js',
},
子应用的 expose 也配了,remoteEntry.js 能直接在浏览器打开,但主应用就是加载不了,到底哪里出问题了?
你确认 remoteEntry.js 能直接在浏览器打开,这说明文件确实存在,但主应用通过 fetch/XHR 加载它的时候,浏览器会因为跨域限制把它拦下来。
解决步骤
第一步:修改子应用的 webpack devServer 配置
在你的子应用(localhost:3001)的 webpack 配置里,加上 CORS 相关的 headers:
原理是这样:浏览器加载 remoteEntry.js 时会先发一个 OPTIONS 预检请求,确认服务器是否允许跨域访问。子应用服务器没有返回正确的 CORS 头,浏览器就直接把请求 block 掉了,返回给你一个 404 或者网络错误。
第二步:确认子应用的 ModuleFederationPlugin 配置
确保子应用暴露模块的方式是对的:
第三步:主应用正确消费
主应用那边这样引用:
排查技巧
打开浏览器开发者工具的 Network 面板,刷新页面,看 remoteEntry.js 的请求详情:
- 如果 Status 是 (failed) net::ERR_NAME_NOT_RESOLVED,说明域名解析有问题
- 如果 Status 是 404,看看请求的 URL 对不对
- 如果 Status 是 200 但没有响应体,看看是不是 CORS 问题
- 看 Response Headers 里有没有 Access-Control-Allow-Origin,如果没有就是后端没配置好
还有一点提醒一下,如果你用的是 webpack-dev-server,版本要在 4.0.0 以上才完全支持 Module Federation。
配置改完记得重启子应用的 devServer,跨域配置不会热更新的。