5月30日 23:35

Module Federation 是什么?它为什么能运行时加载模块?

Module Federation 是 Webpack 5 提供的运行时模块联邦能力,它允许一个应用在运行时加载另一个应用暴露出来的模块。简单说,remote 负责把组件、页面或工具函数暴露成可被消费的模块,host 负责在需要时加载 remoteEntry.js,再从远程容器里取模块执行。它和传统 npm 包最大的区别是:npm 包在构建前就固定进产物,Module Federation 可以在运行时拿到远程应用刚发布的代码。

追问

remoteEntry.js 在里面扮演什么角色?

remoteEntry.js 可以理解为远程应用的模块目录和运行时入口,它记录了 exposes 暴露了哪些模块,以及这些模块对应的异步 chunk 怎么加载。host 先加载这个入口,拿到远程容器,再调用 container.get('./Button') 获取模块工厂。边界是 remoteEntry 不应该太大,它只是入口和映射,不该把大量业务实现塞进去。踩坑是 CDN 缓存了旧 remoteEntry,而新 chunk 已经发布,host 会按旧映射请求不存在的文件。

Host 和 Remote 必须互相知道对方吗?

Remote 不需要知道谁会消费它,只要暴露稳定的模块路径和依赖约定即可。Host 需要知道 remote 的容器名、入口地址和模块路径,这些可以写死在构建配置里,也可以通过 manifest 动态下发。取舍是静态配置简单可靠,但灰度和多环境切换不灵活;动态配置灵活,却要求配置服务、白名单和失败兜底更完善。对外暴露的模块路径最好当成 API 管理,随便改名会让 host 运行时直接失败。

js
new ModuleFederationPlugin({ name: 'profile', filename: 'remoteEntry.js', exposes: { './UserCard': './src/UserCard' }, shared: { react: { singleton: true, requiredVersion: '^18.2.0' } } })

shared 依赖为什么是它的核心能力?

如果没有 shared,每个 remote 都会带自己的 React、组件库和工具库,微前端很快变成“重复下载大赛”。shared 让应用在运行时协商依赖版本,尽量复用已经加载的实例,尤其适合 React 这类需要单例的库。边界是它只能解决依赖共享,不保证业务状态天然一致,也不会自动处理破坏性升级。版本范围写得太宽会埋兼容性雷,写得太死又会让团队升级困难。

Module Federation 和 npm 包复用怎么取舍?

npm 包适合稳定、通用、发布频率可控的代码,比如工具函数、基础组件和 SDK。Module Federation 适合需要独立部署、跨团队实时交付、和页面强绑定的业务模块。取舍是 npm 更确定、更容易测试,MF 更灵活但运行时风险更多。一个实用边界是:基础能力先做 npm 包,变化快的业务页面或可插拔模块再考虑 MF。

它适合所有微前端项目吗?

不适合。团队技术栈统一、构建链路可控、需要模块级共享时,Module Federation 很合适;如果主要诉求是接入历史系统、隔离全局变量和样式,qiankun 这类应用级方案可能更省心。它带来的真正成本在治理:远程模块契约、shared 版本、监控告警、缓存策略和回滚机制都要有人负责。把这些边界想清楚,Module Federation 才是架构能力,而不是线上随机加载脚本。

标签:Module Federation