配了三年微前端,每次想独立部署一个模块都要和整个构建系统搏斗——今天 Module Federation 2.0 把这件事从根上彻底变了

配了三年微前端,每次想独立部署一个模块都要和整个构建系统搏斗——今天 Module Federation 2.0 把这件事从根上彻底变了。


你可能知道 Module Federation 是 Webpack 5 带来的跨应用代码共享能力。它的核心场景是:多个团队各自开发一个子应用,然后从同一个 Host 动态加载这些 Remote 模块,不用把所有代码打包在一起。

但如果你用过 1.0 版本,大概踩过这几个坑:

第一,类型全靠手写。 Remote 暴露出去的组件,你的 IDE 根本不认识它。你得自己维护一份 .d.ts 文件,Remote 那边改了个 prop,你这边编译一点提示都没有。

第二,Shared 依赖总是打包全量。 你声明 React 要共享,结果整个 React 包都被塞进了 Remote bundle,即使你只用到其中一个 hook。团队一多,每个人的 Shared 版本还不一定一致。

第三,没有调试工具。 线上模块加载失败了,你只能靠 Network 面板一个个猜是哪个 Remote 出了问题。

这些问题在 Module Federation 2.0 里面基本都被修了。


1. 动态类型提示:Remote 模块也有补全了

2.0 在构建时会自动把 .d.ts 文件打包进 Remote container。这意味着你在 Host 端引用 Remote 组件时,IDE 能直接拿到完整的类型信息。

来看一个实际配置:

// webpack.config.js(Host 端)
const { ModuleFederationPlugin } = require("webpack").container;
const { DependsOnPlugin } = require("@module-federation/enhanced");

module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      name: "host",
      remotes: {
        // entry 地址指向 Remote 的 mf-manifest.json
        cart: "cart@https://cart.example.com/remoteEntry.js",
      },
      shared: {
        react: { singleton: true, requiredVersion: "^18.3.0" },
        "react-dom": { singleton: true, requiredVersion: "^18.3.0" },
      },
    }),
  ],
};

Remote 那边用 @module-federation/enhanced 暴露组件:

// webpack.config.js(Remote 端)
const { ModuleFederationPlugin } = require("@module-federation/enhanced/rspack");

module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      name: "cart",
      exposes: {
        "./CartWidget": "./src/CartWidget.tsx",
        "./CartPage": "./src/pages/CartPage.tsx",
      },
      shared: { react: { singleton: true } },
    }),
  ],
};

构建完成后,Remote 那边会生成一个 mf-manifest.json,里面包含了所有暴露模块的类型签名。Host 端拿到这个 manifest,IDE 就能做补全了。


2. Tree Shaking:Shared 依赖终于按需打包了

这是 2.0 对性能影响最大的一项改进。

之前的问题是:如果你声明 react 要共享,Webpack 会把整个 React 包标记为 shared。但实际上你的 Remote 可能只用到了 useStateuseEffect,结果整个 react/index.js 都被打进去了。

2.0 通过 shared.treeShaking 实现了按需裁剪:

new ModuleFederationPlugin({
  name: "host",
  shared: {
    react: {
      singleton: true,
      requiredVersion: "^18.3.0",
      // 2.0 新增:启用 tree shaking
      treeShaking: true,
    },
  },
});

开启之后,Webpack 会分析你实际用到了哪些 export,只把用到的部分打包进 shared bundle。据官方数据,这个优化在 React + React-DOM 这个组合上能减少约 30-40% 的 shared bundle 大小。

配合 Rspack 使用效果更明显。Rspack 内置了 Module Federation 2.0 支持,Build 速度比 Webpack 快 5-10 倍:

// rspack.config.js(Rspack 原生支持 2.0)
import { rspack } from "@rspack/core";

export default {
  plugins: [
    new rspack.container.ModuleFederationPlugin({
      name: "host",
      shared: {
        react: { singleton: true, treeShaking: true },
      },
    }),
  ],
};

3. Runtime Plugin:不用重载页面也能换 Remote

这是 2.0 最有趣的能力。1.0 的 Remote 列表是在构建时写死的,如果想换版本,只能重新部署 Host。

2.0 的 Runtime Plugin 系统允许你在运行时动态修改 Remote 的地址和 Shared 版本:

// runtime-plugin-example.js
export default {
  name: "ab-testing-plugin",
  beforeResolve(args) {
    // 读取 URL 参数决定加载哪个版本的 Remote
    const variant = new URLSearchParams(window.location.search).get("ab");
    if (args.resolveOptions?.shareScope === "stable") {
      return args;
    }
    // 切换到实验组 Remote
    return {
      ...args,
      entry: args.entry.replace("/stable/", "/experiment/"),
    };
  },
};

这个能力让 A/B 测试和用户分群推送变成了零成本的事——不需要重新部署,只要改一下 CDN 上的 manifest 文件,或者在运行时注入不同的 plugin 配置。


4. Chrome DevTools 插件:终于能看见加载图了

Module Federation 2.0 官方出了一个 Chrome 扩展叫 Module Federation Inspector。装上之后,你可以在 DevTools 里直接看到:

  • 当前页面加载了哪些 Remote
  • 每个 Remote 的共享依赖版本
  • 模块加载的先后顺序和时间
  • Shared 依赖的 Tree Shaking 效果

这对于排查「为什么这个页面的 JS 比预期大了 200KB」这类问题非常有用。


2.0 支持哪些构建工具

构建工具 MF 1.0 MF 1.5 MF 2.0
Webpack 5 ✅(需 @module-federation/enhanced)
Rspack ✅(内置) ✅(内置,官方推荐)
Vite ✅(@module-federation/vite,实验性)
Rollup / 其他 ⚙️(遵循 Federation 协议即可)

如果你要从零开始一个新项目,Rspack 是目前最推荐的选择——内置支持、开箱即用、Build 速度快。如果你的团队已经在用 Webpack 5,升级到 2.0 只需要换插件,不需要改业务代码。


三步下一步

第一步:确认你的构建工具是否支持 2.0。 如果用 Webpack,装 @module-federation/enhanced;如果用 Rspack,直接升级到最新版本即可。

第二步:在测试环境跑一遍 Remote 加载流程。 用 DevTools 的 Network 面板和 Module Federation Inspector 观察 shared bundle 的实际大小,和 1.0 时代做个对比。

第三步:打开 Tree Shaking。 在 shared 配置里加一行 treeShaking: true,观察主 bundle 大小变化。如果你的 Remote 数量在三个以上,这个优化的收益会比较明显。


Module Federation 2.0 的本质变化是:它从一个「代码共享工具」变成了一个「微前端架构平台」。Runtime Plugin 让部署策略变得动态,Type Hints 让协作成本降低,Tree Shaking 让性能不再为共享牺牲。这些改变加在一起,才是真正的独立部署——不只是代码能分开跑,而是团队能真正独立工作。

评论区

0 条评论

登录后可评论。

阿柯·前端架构 13 阅读