前端阅读 05月30日 23:22
现有应用如何平稳迁移到 Module Federation?
把现有应用迁移到 Module Federation,最忌讳一上来就按团队边界大拆。更稳的路线是先让老应用作为 Shell 保持不动,再把低风险页面、公共组件或独立业务域拆成 remote,等发布、监控、回滚都跑顺后再扩大范围。迁移的本质不是换插件,而是改变构建、发布和依赖协作方式。迁移前先看哪些条件?先评估三件事:应用是否有清晰的业务边界,依赖版本是否可统一,发布链路是否支持多产物部署。如果当前项目连 React、路由、状态库版本都混乱,直接上联邦只会把问题放大。还要看团队协作方式:Module Federation 适合多个团队独立交付,不适合一个小团队为了“微前端”而强拆。// shell webpack.config.jsnew ModuleFederationPlugin({ name: 'shell', remotes: { user: 'user@https://cdn.example.com/user/remoteEntry.js' }, shared: { react: { singleton: true, requiredVersion: '^18.2.0' }, 'react-dom': { singleton: true, requiredVersion: '^18.2.0' } }})这段配置看起来简单,真正的边界在 shared。版本写得太宽,可能引入未知兼容问题;写得太死,又会让 remote 发布受 Shell 牵制。一般建议框架类依赖单例且收紧版本,工具类依赖按体积和兼容性决定是否共享。迁移策略怎么选?第一种是“壳保留,页面外拆”:老应用继续负责登录、菜单、路由和全局布局,新业务页面逐步变成 remote。这种风险最低,适合后台系统和中大型 ToB 应用。第二种是“组件先行”:先拆设计系统、图表、富文本、上传器这类公共组件。好处是收益快,但要注意样式隔离和 peer dependency,否则公共组件一升级,多个业务同时出问题。第三种是“按业务域拆分”:订单、用户、营销各自独立构建和发布。它最符合微前端理想状态,但要求团队边界、接口契约、监控和回滚都比较成熟。路由和发布怎么兜底?迁移期必须把 remote 加载失败当成常态处理。Shell 不应该因为一个 remoteEntry 404 就白屏,而要展示降级页、错误边界或回退到旧页面。发布时建议 remote 使用不可变版本路径,Shell 读取一份可回滚的 manifest。const RemoteUser = React.lazy(() => import('user/App').catch(() => import('./fallback/UserFallback')))这类兜底不是锦上添花,而是迁移能不能上线的前提。尤其灰度阶段,新旧页面可能同时存在,日志里必须能区分用户命中了哪个 remote 版本。数据、样式和权限要不要一起拆?不要急着一起拆。页面可以先联邦化,但登录态、权限、主题和埋点最好仍由 Shell 统一提供,remote 通过明确的 props、事件或 SDK 获取上下文。否则每个 remote 都复制一套鉴权和埋点,迁移后看似独立,实际排查问题更慢。样式也要提前约定:CSS Modules、Shadow DOM、前缀命名或设计系统变量至少选一种,否则新旧页面并存时很容易互相污染。追问应该先拆公共组件还是业务页面?如果团队第一次做 Module Federation,优先拆低风险业务页面,而不是核心公共组件。业务页面失败时可以路由回退,公共组件失败会影响多个页面,事故半径更大。公共组件适合在共享依赖、样式隔离和版本发布流程稳定后再拆。取舍点是页面拆分收益慢一点,但更容易把迁移风险控制在单个业务域内。迁移时 shared 依赖怎么定?React、ReactDOM、路由和状态管理这类运行时强相关依赖,通常要设 singleton。lodash、dayjs 这类工具库是否共享,要看体积、版本差异和缓存收益,不要为了“少打包一点”制造版本耦合。踩坑最多的是 remote 自己带了一份 React,Shell 也有一份,最后 hooks 报错却很难定位。边界是共享依赖只能解决前端运行时复用,不能替代包管理和版本治理。如何判断迁移已经可以扩大范围?看四个信号:remote 加载失败有降级,发布后能快速回滚,监控能看到加载耗时和错误率,团队知道谁负责哪个 remote。只要其中一个缺失,就不要急着拆核心链路。迁移不是拆得越快越好,而是每拆一块都能独立发布、独立定位、独立恢复。很多项目失败不是技术不通,而是拆完之后没有人对线上 remote 负责。老项目不是 Webpack 还能迁移吗?可以,但要先确认当前构建工具的联邦插件成熟度。Vite、Rspack、Rsbuild 都有方案,但不同插件对 CSS、动态 remote、SSR 和 shared 的支持细节不一样。稳妥做法是先做一个真实业务切片验证,而不是只跑 demo。边界是如果项目强依赖老旧 loader、全局变量和隐式副作用,迁移前要先整理工程结构。