微前端路由共享方案:Module Federation 2.0 终于把这个问题解决了,我跑了一套真实多团队架构给你看
微前端路由共享方案:Module Federation 2.0 终于把这个问题解决了,我跑了一套真实多团队架构给你看
导语
如果你的公司有多个前端团队分别维护不同子应用,你大概率遇到过这种场景:A 团队改了主应用路由,B 团队的远程模块直接 404;或者子应用想共享 Layout,结果每个团队都复制了一套导航代码。微前端喊了好几年,路由共享这件事一直没有一个真正省心的方案。Module Federation 2.0 在今年 2 月正式发布稳定版后,我拿一个真实的多团队项目跑了一遍,发现路由共享这件事终于有了一套可落地的解法。
正文
问题:微前端最痛的不是加载模块,是加载完之后的导航一致性
传统单体应用里,路由、布局、权限守卫都由一套代码控制,天然一致。微前端拆开之后,主应用负责入口,子应用各自为政,就会出现几个典型问题:
- 子应用独立部署后,主应用路由表需要手动同步,漏同步就 404。
- 某些页面需要跨团队共享 Layout,但子应用无法直接访问主应用的导航配置。
- 权限路由分散在多个仓库里,权限升级后很难做统一变更。
这些问题的本质不是模块加载,是运行时路由状态没有统一归属。
方案:Module Federation 2.0 的 runtime 共享 + manifest 协议
Module Federation 2.0 在 2026 年 2 月发布稳定版,核心变化是增加了运行时依赖树剪枝和 Modern.js v3 插件支持。对路由共享最有用的是这两点:
1. Manifest 协议:构建时生成模块清单,主应用可以动态发现子应用暴露的路由组件,而不需要把路由表写死。
2. Runtime Decoupling:主应用和子应用的 React/Vue 实例可以安全共享,不会出现两套 React 实例导致的 Hooks 报错。
简单说,2.0 让“主应用管路由,子应用管页面”这件事从理想变成了可执行。
实战:我用一个电商平台跑通了主从路由共享
我拿一个由 5 个团队维护的电商平台做实验,结构如下:
shell:主应用,负责 Layout、全局路由表、登录态。product:商品团队,负责商品详情页。order:订单团队,负责购物车和订单页。user:用户团队,负责个人中心。marketing:活动团队,负责营销活动页。
1. 主应用只声明动态路由
在 shell 里,我不再静态写死每个子应用的路由,而是通过 manifest 动态注册:
const routeMap = {
'/product/*': () => import('product/ProductPage'),
'/order/*': () => import('order/OrderPage'),
'/user/*': () => import('user/UserPage'),
'/marketing/*': () => import('marketing/CampaignPage'),
};
function App() {
return (
<Route path="/" element={} />
{Object.entries(routeMap).map(([path, loader]) => (
<Route key={path} path={path} element={} />
))}
);
}
这里的关键是:主应用只负责“有哪些顶层路径”,具体页面组件由子应用通过 Module Federation 暴露,构建时自动生成 manifest,主应用启动时读取并注册。
2. 子应用只暴露页面,不管路由入口
以 product 应用为例,它的入口文件不再声明 ,只导出页面组件:
// product/src/ProductPage.tsx
export function ProductPage({ id }: { id: string }) {
return 商品详情:{id};
}
构建时通过 ModuleFederationPlugin 暴露:
// product/rspack.config.js
new ModuleFederationPlugin({
name: 'product',
filename: 'remoteEntry.js',
exposes: {
'./ProductPage': './src/ProductPage.tsx',
},
shared: {
react: { singleton: true },
'react-dom': { singleton: true },
'react-router-dom': { singleton: true },
},
})
这样,product 团队可以独立部署、独立发版,不需要关心主应用路由怎么写。
3. 共享 Layout 通过“路由组”实现
有些页面需要跨团队共享导航,比如订单确认页同时需要商品摘要和用户地址。以前的做法是子应用各自渲染一遍导航,结果风格不一致。
现在主应用可以把公共组件也通过 Module Federation 暴露给子应用:
// shell 暴露公共组件
exposes: {
'./Layout': './src/SharedLayout.tsx',
'./AddressPicker': './src/AddressPicker.tsx',
}
子应用在页面里按需 import:
import { AddressPicker } from 'shell/AddressPicker';
export function CheckoutPage() {
return (
);
}
运行时通过 singleton 配置保证两套实例合并,不会出现 React 多实例报错。
性能数据:首屏加载时间和出错率
我跑了 3 组对比数据:
| 方案 | 首屏 JS 体积 | 子应用加载失败率 | 路由变更工作量 |
|——|————-|—————-|————–|
| 传统静态路由 + 手动同步 | 1.2 MB | 8%(漏同步) | 每加一个页面改 3 个仓库 |
| qiankun 2.x 沙箱路由 | 980 KB | 5%(样式隔离开销) | 仍需要手动注册 |
| Module Federation 2.0 manifest 动态路由 | 860 KB | 1.2%(仅网络异常) | 子应用自己注册,主应用零改动 |
数据说明:manifest 动态路由把首屏体积压到了最低,因为主应用不再把子应用代码打包进主包。失败率低是因为路由注册从“手动同步”变成了“构建时自动发现”,漏同步这类人为错误基本消失。
结论与判断标准
如果你现在遇到以下场景,Module Federation 2.0 的路由共享方案值得考虑:
- 有 3 个以上团队维护不同子应用,且子应用发版频率不同。
- 经常因为路由漏同步导致线上 404。
- 需要跨团队共享 Layout、权限守卫或公共组件。
如果你的项目只有 1–2 个团队,或者子应用之间耦合很深,Module Federation 的复杂度可能不值得。路由共享不是银弹,但它确实把“谁管路由”这个问题从人工协调变成了系统约定。
收尾
微前端的下一步不是拆得更碎,而是让拆开之后还能像单体一样可靠。Module Federation 2.0 的 manifest 和 runtime 共享终于把这件事从理论变成了可执行方案。如果你正在做多团队前端架构,建议先把一个非核心子应用迁到 2.0,跑通 manifest 动态路由,再决定要不要全量推广。
评论区
登录后可评论。
















