Module Federation 中远程模块加载失败怎么办?

瑞娜(打工版) 阅读 29

我在用 Webpack 5 的 Module Federation 搭微前端,主应用能正常启动,但加载远程子应用时一直报错“Container initialization failed”,控制台显示 404。

我确认子应用已经运行在 http://localhost:3001,而且在主应用的 webpack 配置里也正确声明了 remote:

remotes: {
  app2: 'app2@http://localhost:3001/remoteEntry.js',
},

子应用的 expose 也配了,remoteEntry.js 能直接在浏览器打开,但主应用就是加载不了,到底哪里出问题了?

我来解答 赞 12 收藏
二维码
手机扫码查看
1 条解答
夏侯嘉兴
这个问题很常见,十有八九是 CORS 的问题。

你确认 remoteEntry.js 能直接在浏览器打开,这说明文件确实存在,但主应用通过 fetch/XHR 加载它的时候,浏览器会因为跨域限制把它拦下来。

解决步骤

第一步:修改子应用的 webpack devServer 配置

在你的子应用(localhost:3001)的 webpack 配置里,加上 CORS 相关的 headers:

// 子应用的 webpack.config.js
devServer: {
port: 3001,
headers: {
// 这两行是关键,允许任何来源访问
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
'Access-Control-Allow-Headers': 'X-Requested-With, content-type, Authorization',
},
},


原理是这样:浏览器加载 remoteEntry.js 时会先发一个 OPTIONS 预检请求,确认服务器是否允许跨域访问。子应用服务器没有返回正确的 CORS 头,浏览器就直接把请求 block 掉了,返回给你一个 404 或者网络错误。

第二步:确认子应用的 ModuleFederationPlugin 配置

确保子应用暴露模块的方式是对的:

// 子应用
new ModuleFederationPlugin({
name: 'app2', // 这个 name 必须和主应用 remotes 里的 'app2' 对应
filename: 'remoteEntry.js', // 默认就是这个文件名
exposes: {
'./MyComponent': './src/MyComponent', // 暴露的模块路径
},
// ... 其他配置
})


第三步:主应用正确消费

主应用那边这样引用:

// 主应用 index.js
import React from 'react';
// 方式一:直接异步加载
const MyComponent = React.lazy(() => import('app2/MyComponent'));

// 方式二:也可以这样用
import('app2/MyComponent').then(module => {
console.log(module.default);
});


排查技巧

打开浏览器开发者工具的 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,跨域配置不会热更新的。
点赞
2026-03-17 15:00