什么是Module Federation2

Module Federation2概念

模块联合是一种 JavaScript 应用去中心化的架构模式(类似于服务器端的微服务)。它允许您在多个 JavaScript 应用程序(或微前端)之间共享代码和资源。这可以帮助您:

  1. 减少代码重复

  2. 提高代码可维护性

  3. 降低应用程序的整体大小

  4. 增强应用程序的性能

module federationv1和v2的区别是什么?

Module Federation 2.0 与 Webpack5 内置的 Module Federation 不同,它不仅提供模块导出、加载和依赖共享等核心功能,还提供额外的动态类型提示、Manifest、Federation Runtime 和 Runtime Plugin System。这些特性使得 Module Federation 更适合用作大型 Web 应用程序中的微前端架构。

特点

  • 代码共享、依赖复用
  • 资源清单(Manifest)
  • module federation runtime
  • 运行时插件系统(tapable实现)
  • 动态类型提示
  • Chrome 开发工具
  • Rspack 和 Webpack 支持

模块联邦并没有样式隔离机制, 这意味着, 当主子应用很有可能会互相造成样式污染

概念理解:生产者

通过 Module federation 构建插件设置了 exposes 暴露其他模块给其他 JavaScript 应用消费的应用在 Module federation 中称之为 Provider(生产者),生产者可以同时作为一个消费者。

概念理解:消费者

通过 Module federation 构建插件设置了 remotes 消费其他生产者的模块称之为 Consumer (消费者),消费者可以同时作为一个生产者。

@module-federation/enhanced

Module Federation 核心包,作为 Webpack 构建插件、 Rspack 构建插件、Runtime 入口依赖。

@module-federation/runtime

Module Federation 的 Runtime 包,通常使用 @module-federation/enhanced 来使用 Runtime 能力,若不需要使用构建工具时可单独安装此包。

概念目标

  • 它既可以暴露,又可以使用 webpack 支持的任何模块类型

  • 代码块加载应该并行加载所需的所有内容(web:到服务器的单次往返)

  • 从使用者到容器的控制

    • 重写模块是一种单向操作
    • 同级容器不能重写彼此的模块。
  • 概念适用于独立于环境

    • 可用于 web、Node.js 等
  • 共享中的相对和绝对请求

    • 会一直提供,即使不使用
    • 会将相对路径解析到 config.context
    • 默认不会使用 requiredVersion
  • 共享中的模块请求

    • 只在使用时提供
    • 会匹配构建中所有使用的相等模块请求
    • 将提供所有匹配模块
    • 将从图中这个位置的 package.json 提取 requiredVersion
    • 当你有嵌套的 node_modules 时,可以提供和使用多个不同的版本
  • 共享中尾部带有 / 的模块请求将匹配所有具有这个前缀的模块请求


使用

目前 Module Federation 提供了两种注册模块和加载模块的方式:

  1. 一种是在构建插件中声明(一般是在 module-federation.config.ts 文件中声明)

  2. 另一种方式是直接通过 runtime 的 api 进行模块注册和加载。

两种模式并不冲突可结合使用。你可以根据你的实际场景灵活选取模块注册方式和时机

运行时注册模块和构建配置注册模块的区别如下:

运行时注册模块 插件中注册模块
可脱离构建插件使用,在 webpack4 等项目中可直接使用纯运行时进行模块注册和加载 构建插件需要是 webpack5 或以上
支持动态注册模块 不支持动态注册模块
不支持 import 语法加载模块 支持 import 同步语法加载模块
支持 loadRemote 加载模块 支持 loadRemote 加载模块
设置 shared 必须提供具体版本和实例信息 设置 shared 只需要配置规则即可,无须提供具体版本及实例信息
shared 依赖只能供外部使用,无法使用外部 shared 依赖 shared 依赖按照特定规则双向共享
可以通过 runtimeplugin 机制影响加载流程 目前不支持提供 plugin 影响加载流程
不支持远程类型提示 支持远程类型提示

插件用法

快速创建项目

Module Federation 提供了 create-module-federation 工具来创建项目,不需要全局安装,直接使用 npx 按需运行即可。

模板

在创建项目时,你可以选择 create-module-federation 提供的下列模板:

模板 描述
provider-modern 使用 Modern.js 的生产者
provider-rsbuild 使用 Rsbuild 的生产者
provider-rslib 使用 Rslib 的生产者
provider-rslib-storybook 使用 Rslib 的生产者,并且开启了 storybook 功能
consumer-modern 使用 Modern.js 的消费者
consumer-rsbuild 使用 Rsbuild 的消费者

生产者, 提供组件

bash 复制代码
# 创建 my-project目录下创建mf-provider的生产者
npx create-module-federation --dir my-project --template provider-modern --name mf-provider
js 复制代码
import { createModuleFederationConfig } from "@module-federation/rsbuild-plugin";

export default createModuleFederationConfig({
  name: "mf-provider",
  exposes: {
    "./Provider": "./src/components/ProviderComponent.tsx",
  },
  shared: {
    react: { singleton: true },
    "react-dom": { singleton: true },
  },
});

消费者, 使用生产者

bash 复制代码
# 创建 my-project目录下创建mf-consumer的消费者
npx create-module-federation --dir my-project --template consumer-modern --name mf-consumer
js 复制代码
import { createModuleFederationConfig } from "@module-federation/rsbuild-plugin";

export default createModuleFederationConfig({
  name: "mf-consumer",
  remotes: {
    provider: "mf-provider@http://localhost:3001/mf-manifest.json",
  },
  shareStrategy: "loaded-first",
  shared: {
    react: { singleton: true },
    "react-dom": { singleton: true },
  },
});

import Provider from "provider/Provider";
<Provider></Provider>;

runtime用法

module federation v2允许我们在写运行时代码去加载远程模块,但是远程模块的导出还是交给了构建工具基于@module-federation/runtime去实现

example1

example2

这个git项目内还有很多使用案例

模块加载

tsx 复制代码
// 如果没有使用构建插件,那么可以创建新的实例,并注册模块
import { createInstance } from '@module-federation/enhanced/runtime';
import React from 'react';

const mf = createInstance({
  name: 'mf_host',
  remotes: [
    {
      name: 'remote1',
      alias: 'remote-1',
      entry: 'http://localhost:3001/mf-manifest.json',
    }
  ]
});

export default () => {
  const MyButton = React.lazy(() =>
    mf.loadRemote('remote1').then(({ MyButton }) => {
      return {
        default: MyButton
      };
    }),
  );

  return (
    <React.Suspense fallback="Loading Button">
      <MyButton />
    </React.Suspense>
  );
}

原理

  • 通过share的模块回自动在执行链路过程中生成share scope,而本地host和remote都会进行提供相对应的modules, 在进行使用的时候通过校验share scope中的provided模块是否符合当前的版本等信息,如果符合则进行加载模块并存储,从而达到了共享模块的母的

  • 模块加载是通过异步加载,只有在使用的时候才会进行加载对应的模块内容,在未加载前只存储对应的相关模块属性信息

juejin.cn/post/704812...

相关推荐
岁月玲珑几秒前
ComfyUI如何配置启动跳转地址127.0.0.1但是监听地址是0.0.0.0,::
java·服务器·前端
wuk9989 分钟前
Webpack技术深度解析:模块打包与性能优化
前端·webpack·性能优化
Moment30 分钟前
Cursor 2.0 支持模型并发,我用国产 RWKV 模型实现了一模一样的效果 🤩🤩🤩
前端·后端·openai
狂炫冰美式39 分钟前
QuizPort 1.0 · 让每篇好文都有测验陪跑
前端·后端·面试
咋吃都不胖lyh1 小时前
.docx 和 .doc 是 Microsoft Word 文档的两种主要文件格式
前端·html·xhtml
哈乐1 小时前
网工应用题:配置命令补全类题目
服务器·前端·网络
uuai1 小时前
echarts不同版本显示不一致问题
前端·javascript·echarts
AKclown1 小时前
基于Monaco的diffEditor实现内容对比
前端·vue.js·react.js
摆烂工程师2 小时前
(2025年11月)开发了 ChatGPT 导出聊天记录的插件,ChatGPT Free、Plus、Business、Team 等用户都可用
前端·后端·程序员
gongzemin2 小时前
使用阿里云ECS部署前端应用
前端·vue.js·后端