模块联邦
约 645 字大约 2 分钟
2026-02-11
模块联邦(Module Federation)是 Webpack 5 的关键能力,它解决的是:
- 多个独立前端应用如何在运行时共享模块。
- 微前端场景下如何避免重复打包公共依赖。
- 应用间如何独立发布而不强绑定构建。
先理解角色:Host 与 Remote
- Host:消费远程模块的一方。
- Remote:暴露模块给外部的一方。
- Shared:双方共享的公共依赖(例如 React)。
| 配置 | 解决的问题 | 示例 |
|---|---|---|
name | 容器唯一标识 | host_app |
filename | Remote 清单入口文件 | remoteEntry.js |
remotes | Host 如何找到远程容器 | remote_app@http://.../remoteEntry.js |
exposes | Remote 暴露哪些模块 | ./Button: ./src/Button.js |
shared | 如何去重并约束依赖版本 | react / react-dom |
核心配置项与作用
Remote 端配置(为什么这么写)
Remote 端重点是两件事:
- 对外暴露模块。
- 提供可被 Host 加载的
remoteEntry.js。
const { container } = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ModuleFederationPlugin = container.ModuleFederationPlugin;
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
// Remote 资源加载基础地址
publicPath: 'http://localhost:9001/',
},
devServer: {
port: 9001,
headers: {
// 本地联调时允许跨域加载 remoteEntry
'Access-Control-Allow-Origin': '*',
},
},
plugins: [
new ModuleFederationPlugin({
name: 'remote_app',
filename: 'remoteEntry.js',
exposes: {
'./Button': './src/Button.js',
},
shared: {
react: { singleton: true, requiredVersion: false },
'react-dom': { singleton: true, requiredVersion: false },
},
}),
new HtmlWebpackPlugin({ template: './public/index.html' }),
],
};Host 端配置(为什么这么写)
Host 端关键点是:告诉运行时“去哪加载远程容器”。
const { container } = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ModuleFederationPlugin = container.ModuleFederationPlugin;
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
publicPath: 'http://localhost:9000/',
},
devServer: {
port: 9000,
},
plugins: [
new ModuleFederationPlugin({
name: 'host_app',
remotes: {
remote_app: 'remote_app@http://localhost:9001/remoteEntry.js',
},
shared: {
react: { singleton: true, requiredVersion: false },
'react-dom': { singleton: true, requiredVersion: false },
},
}),
new HtmlWebpackPlugin({ template: './public/index.html' }),
],
};远程模块调用示例:
import('remote_app/Button')
.then(({ default: Button }) => {
console.log('Remote loaded:', Button);
})
.catch((error) => {
console.error('Remote load failed:', error);
});运行时加载流程
- Host 先加载
remoteEntry.js。 - 远程容器注册可用模块映射。
- Host 在
import('remote/xxx')时请求远程模块。 - 运行时协商 shared 依赖版本并实例化模块。
使用注意事项
建议
shared依赖尽量声明singleton,避免多实例冲突。- remote 地址通过环境变量管理,便于多环境切换。
- 远程模块加载失败必须有降级 UI。
常见错误
remoteEntry.js地址写错或端口未启动。- CORS 未放行导致远程脚本无法加载。
- shared 版本策略不清晰,触发运行时冲突。
最佳实践
- 先从低耦合模块开始联邦化(组件库、低频业务块)。
- 设计清晰的 Remote API 边界,避免跨应用强依赖内部实现。
- 将联邦健康检查纳入发布流程。
