React 用 Module Federation 拆巨石应用:独立部署的子应用与主应用运行时组合
test12026-10-121 次阅读
为什么需要模块联邦
当多个团队在同一套 React 代码库里互相阻塞,或者一个功能上线要等整个巨石应用重新构建,模块联邦(Module Federation)能把应用拆成多个可独立构建、独立部署的子应用,在运行时由浏览器拼装。它解决的是“构建期解耦”和“运行时共享”两个痛点。
用 @module-federation/enhanced 配置主子应用
现代方案推荐 Webpack 5 内置或 Rspack 的 @module-federation/enhanced。下面是一组最小配置:子应用暴露组件,主应用远程加载。
// host 主应用:webpack/rspack 配置片段
import { ModuleFederationPlugin } from '@module-federation/enhanced';
export default {
plugins: [
new ModuleFederationPlugin({
name: 'host',
remotes: {
cart: 'cart@https://cart.example.com/remoteEntry.js',
},
shared: {
react: { singleton: true, requiredVersion: '^18.0.0' },
'react-dom': { singleton: true, requiredVersion: '^18.0.0' },
},
}),
],
};
// cart 子应用:暴露一个远程组件
new ModuleFederationPlugin({
name: 'cart',
filename: 'remoteEntry.js',
exposes: {
'./CartButton': './src/CartButton.tsx',
},
shared: {
react: { singleton: true, requiredVersion: '^18.0.0' },
'react-dom': { singleton: true, requiredVersion: '^18.0.0' },
},
});
在 React 里懒加载远程组件
远程组件本质是一个异步模块,用 React.lazy 包裹即可接入 Suspense。
import { lazy, Suspense } from 'react';
const CartButton = lazy(() => import('cart/CartButton'));
export function Header() {
return (
<header>
<h2>商城</h2>
<Suspense fallback={<span>加载购物车…</span>}>
<CartButton />
</Suspense>
</header>
);
}
工程落地要点
- shared 里给 react / react-dom 设 singleton: true,避免运行期出现两个 React 实例导致 hooks 报错。
- 子应用独立部署后,主应用通过 remoteEntry.js 的 URL 在运行时拉取,发布子应用不需要重新构建主应用。
- 类型共享:把子应用导出的 props 类型单独发包,或用 tsconfig paths 指向本地 dts 文件,避免主应用写错 props。
- 版本冲突:shared 的 requiredVersion 决定主子应用能否复用同一份依赖,设置不当会静默多份打包。
T
test1
文章作者
为什么需要模块联邦 当多个团队在同一套 React 代码库里互相阻塞,或者一个功能上线要等整个巨石应用重新构建,模块联...
- 分类
- 技术
- 发布时间
- 2026-10-12
- 字数
- 约 1704 字
- 阅读
- 1 次
