Module Federation 与 EMP 学习笔记
适合目标:系统掌握模块联邦思路,理解它与传统运行时微前端的本质差异,并能用于 React 或统一工程体系项目。
学习定位:这一份偏“模块级拆分、远程共享、工程化架构”。
学习原则:先理解为什么它不是传统整应用托管,再理解共享依赖与远程模块的价值。
目录
- Module Federation 是什么
- 它和传统微前端的区别
- 核心概念
- 基础接入
- 共享依赖与版本策略
- React 场景下怎么用
- Vue 场景下怎么用
- EMP 怎么理解
- 进阶治理
- 常见问题
- 面试考点
- 一页总结
1. Module Federation 是什么
Module Federation 是 Webpack 5 提供的一种远程模块共享能力。
它的核心思想是:
让一个应用在运行时加载另一个应用暴露出来的模块。
比如:
- 主应用远程加载一个页面模块
- 一个业务应用远程加载共享组件
- 多个系统共用同一套设计系统模块
它不是先把“整应用”接进来,而是先把“模块”共享起来。
2. 它和传统微前端的区别
2.1 传统运行时微前端更像“应用托管”
代表:
- Qiankun
- 无界
- MicroApp
关注点:
- 子应用如何挂载
- 路由如何激活
- 生命周期如何管理
- 隔离如何做
2.2 Module Federation 更像“远程模块系统”
关注点:
- 模块如何暴露
- 模块如何远程消费
- 公共依赖如何共享
- 多应用如何协同构建
2.3 一句话区分
运行时微前端:我把一个完整子应用接进来模块联邦:我把一个远程模块像本地模块一样使用
3. 核心概念
3.1 Host 和 Remote
Host
消费远程模块的应用。
Remote
暴露模块给其他应用消费的应用。
3.2 Exposes
表示当前应用对外暴露哪些模块。
例如:
- 页面组件
- 业务组件
- hooks
- 工具模块
3.3 Remotes
表示当前应用依赖哪些远程模块。
3.4 Shared
表示多个应用之间共享依赖,比如:
- React
- React DOM
- Vue
- UI 组件库
3.5 singleton 和版本策略
重点在于:
- 是否只允许单例
- 版本不一致怎么处理
- 是否允许 fallback
4. 基础接入
4.1 Remote 暴露模块
概念性配置示意:
new ModuleFederationPlugin({
name: 'product_app',
filename: 'remoteEntry.js',
exposes: {
'./ProductList': './src/pages/ProductList'
},
shared: {
react: { singleton: true },
'react-dom': { singleton: true }
}
})
4.2 Host 消费远程模块
new ModuleFederationPlugin({
name: 'shell',
remotes: {
product_app: 'product_app@http://localhost:3001/remoteEntry.js'
}
})
业务代码里再动态引入:
const ProductList = React.lazy(() => import('product_app/ProductList'))
4.3 最小接入流程
- Remote 配置
name、filename、exposes - Host 配置
remotes - 双方约定共享依赖
- 用懒加载消费远程模块
- 验证版本和运行时表现
5. 共享依赖与版本策略
5.1 为什么 shared 很关键
因为如果共享策略不对,就会出现:
- React 被加载两份
- 上下文不一致
- hooks 运行异常
- 产物体积变大
5.2 常见共享依赖
reactreact-domvuevue-router- 状态管理库
- 组件库
5.3 singleton 怎么理解
某些依赖必须确保应用之间只有一份实例,比如 React 本身。
否则就可能出现:
- context 不通
- hooks 报错
- 运行时实例冲突
5.4 版本治理建议
- 核心框架尽量统一主版本
- 共享依赖维护兼容矩阵
- 发布前做集成验证
- 不要把所有包都强行 shared
6. React 场景下怎么用
6.1 为什么 React 很适合 Module Federation
- React 组件天然适合模块拆分
- 懒加载与 Suspense 体验自然
- Webpack 生态成熟
- 设计系统、页面模块、业务组件都好拆
6.2 常见架构形态
Shell + 多 Remote 页面设计系统 Remote + 多业务 HostBFF 平台 + 多业务前端联邦
6.3 React 使用建议
- 优先共享 React、React DOM
- 页面级 Remote 用懒加载
- 错误边界必须加上
- 远程模块的降级策略提前设计
6.4 推荐答法
如果用户问“React 现在微前端推荐什么”,一般优先回答:
React 更推荐 Module Federation 或 EMP,因为 React 更容易发挥模块联邦的细粒度共享优势。
7. Vue 场景下怎么用
7.1 Vue 不是不能用 Federation
Vue 也可以使用 Module Federation,但通常你要想清楚:
- 你到底是想做整应用托管
- 还是想做模块共享
如果你的诉求是:
- 子系统独立接入
- 老系统兼容
- 运行时隔离
那 Vue 场景通常先看 MicroApp 或无界。
如果你的诉求是:
- 组件级共享
- 模块远程消费
- 工程体系统一
那才优先考虑 Federation。
7.2 Vue 使用建议
- 统一 Vue 主版本
- 谨慎共享响应式运行时
- UI 组件库共享要做兼容验证
- 路由和状态不要过度跨应用共享
8. EMP 怎么理解
EMP 可以理解成围绕模块联邦思想构建的一套更工程化的微前端能力方案。
学习时你不用先纠结它的全部实现细节,可以先抓住它的定位:
- 基于联邦能力做工程增强
- 更强调体系化接入
- 更适合平台化、标准化推进
你可以把 EMP 理解成:
不是替代 Federation 的概念,而是在联邦思想之上做更完整的工程化支撑。
9. 进阶治理
9.1 降级策略
远程模块失败时必须有兜底方案:
- 降级到本地版本
- 展示错误占位
- 重试加载
- 监控告警
9.2 发布治理
- Remote 独立发布
- Host 不一定重新发布
- 需要关注远程模块兼容性
- 线上必须可回滚
9.3 监控
至少监控:
remoteEntry.js加载成功率- 远程模块初始化耗时
- 共享依赖冲突
- 降级次数
9.4 边界治理
不要因为能共享模块,就把业务边界打碎。
建议:
- 共享通用模块
- 业务模块保持边界
- 大型状态不要跨应用直接共用
10. 常见问题
10.1 React 加载两份导致 hooks 异常
通常是 shared 配置不对。
10.2 远程模块加载失败
通常看:
remoteEntry.js地址- CDN 缓存
- 版本兼容
- 网络异常兜底
10.3 Host 和 Remote 版本不兼容
解决方向:
- 锁主版本
- 做兼容矩阵
- 灰度验证
10.4 为什么感觉比运行时方案更难
因为它对工程体系要求更高,尤其是:
- 构建体系统一
- 依赖治理更严格
- 模块边界设计更重要
11. 面试考点
11.1 Module Federation 的核心价值是什么
答题要点:
- 远程模块共享
- 运行时按需加载
- 多应用共享依赖
- 支持更细粒度拆分
11.2 它和 Qiankun 的核心区别是什么
Qiankun 偏整应用托管和生命周期编排;
Module Federation 偏模块共享和工程层解耦。
11.3 为什么 React 更常和 Federation 搭配
- 组件化拆分自然
- 懒加载体验成熟
- 生态实践更多
11.4 shared 配置为什么重要
因为会影响:
- 依赖是否重复加载
- 框架实例是否一致
- 运行时是否稳定
12. 一页总结
12.1 Module Federation 的关键词
Host、Remote、Exposes、Shared、远程模块、依赖共享。
12.2 适合谁
- React 技术栈团队
- 工程体系较统一的团队
- 想做模块级拆分和共享的团队
12.3 记忆口诀
不是接整应用,而是把远程模块按本地模块来用。