Module Federation:独立部署、运行时共享组件
本节目标
- 理解 Module Federation 是「模块级」而非「页面级」共享
- 写出一个 remote(暴露组件)和 host(消费组件)的配置
- 知道 remotes / exposes 分别干什么
Module Federation(模块联邦,Webpack 5 / Rspack 原生支持)是微前端的「现代派」:它不切整页,而是让应用之间运行时直接 import 对方的组件/函数,像 import 本地模块一样。每个应用独立部署,谁也不阻塞谁。
设想:组件库团队把 Button 暴露在 remoteLib,业务团队直接 import('remoteLib/Button') 用,业务上线不用等组件库发 npm 包。
// remote 端(组件库项目 webpack.config.js):暴露模块给外界
const { ModuleFederationPlugin } = require('webpack').container
module.exports = {
plugins: [
new ModuleFederationPlugin({
name: 'remoteLib',
filename: 'remoteEntry.js', // 对外暴露的入口文件
exposes: {
'./Button': './src/Button.jsx', // 外界可 import('remoteLib/Button')
'./Modal': './src/Modal.jsx'
},
shared: ['react', 'react-dom'] // 共享 react,避免重复打包(先占位,下节细讲)
})
]
}// host 端(业务项目 webpack.config.js):消费 remote 暴露的模块
const { ModuleFederationPlugin } = require('webpack').container
module.exports = {
plugins: [
new ModuleFederationPlugin({
name: 'hostApp',
remotes: {
// key 是 import 时的前缀,value 是 remote 的入口地址
remoteLib: 'remoteLib@https://cdn.example.com/remoteEntry.js'
},
shared: ['react', 'react-dom']
})
]
}// host 业务代码:像 import 本地一样 import 远程组件(运行时按需加载)
import Button from 'remoteLib/Button'
function Page() {
return <Button>来自远程组件库的按钮</Button>
}关键点:remote 和 host 各自独立构建、独立部署。host 运行时去拉 remoteEntry.js,拿到 remote 暴露的组件定义,再动态加载。哪边先发都行(只要 remoteEntry 地址可达)。这就是它比 qiankun「整页组合」灵活的地方——粒度细到「一个组件」。
名词解释
Module Federation(模块联邦):Webpack 5 / Rspack 的能力,让多个独立构建的应用在运行时互相 import 对方的模块,实现「独立部署 + 模块级共享」。
exposes:remote 端声明「我要对外暴露哪些模块、对应什么路径」(如 ./Button),外界据此路径 import。
remotes:host 端声明「我要消费哪些远程应用、它们的入口在哪」(如 remoteLib@https://.../remoteEntry.js),是消费方的「地址簿」。
remoteEntry.js:remote 端构建产出的「入口清单」文件,里面描述了它暴露了哪些模块、依赖了什么,host 通过这个文件才知道怎么加载。
课后练习
练习 1:Module Federation 和 qiankun 的隔离思路有何不同?
答案:qiankun 是「运行时挂载整页 + 沙箱隔离」,解决页面组合;Module Federation 是「构建期声明共享、运行时 import 模块」,没有沙箱概念,靠构建链保证依赖一致。前者偏「页面自治」,后者偏「组件复用」。
练习 2:host import 一个还没部署的 remote 会怎样?
答案:运行时去拉
remoteEntry.js会 404 / 网络失败,那个动态 import 的组件加载不出来(通常表现为页面报错或加载中)。所以 Module Federation 要求 remote 的入口地址稳定可达,部署顺序上 remote 先就位更稳。
总结
Module Federation 的核心是「构建期 exposes/remotes 声明,运行时 import 远程模块」。粒度细到组件级、各应用独立部署、互不阻塞——这是它相对 qiankun「整页组合」的最大优势。代价是依赖一致性要自己管好(下节的 shared)。下一节讲 shared 依赖与那些容易翻车的坑。