什么是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...

相关推荐
一 乐1 天前
婚纱摄影网站|基于ssm + vue婚纱摄影网站系统(源码+数据库+文档)
前端·javascript·数据库·vue.js·spring boot·后端
C_心欲无痕1 天前
ts - tsconfig.json配置讲解
linux·前端·ubuntu·typescript·json
清沫1 天前
Claude Skills:Agent 能力扩展的新范式
前端·ai编程
yinuo1 天前
前端跨页面通信终极指南:方案拆解、对比分析
前端
yinuo1 天前
前端跨页面通讯终极指南⑨:IndexedDB 用法全解析
前端
xkxnq1 天前
第二阶段:Vue 组件化开发(第 16天)
前端·javascript·vue.js
烛阴1 天前
拒绝配置地狱!5 分钟搭建 Three.js + Parcel 完美开发环境
前端·webgl·three.js
xkxnq1 天前
第一阶段:Vue 基础入门(第 15天)
前端·javascript·vue.js
anyup1 天前
2026第一站:分享我在高德大赛现场学到的技术、产品与心得
前端·架构·harmonyos
BBBBBAAAAAi1 天前
Claude Code安装记录
开发语言·前端·javascript