vite 下使用 Module Federation

Module Federation

Module Federation 的核心是 "打破构建边界,实现模块级的跨应用共享与协同" ,其最佳使用场景需满足以下特征:

  • 应用 / 模块由多团队独立开发维护;
  • 需要复用公共依赖或组件,避免重复打包;
  • 希望简化模块更新流程(免 npm 发布);
  • 需实现微前端、跨技术栈协作或模块级灰度发布。
    注意: 每个应用都可以在 Federation 中暴露 或者加载 远程可共享模块

如何使用 vite 搭建 MF

项目 github 参考地址: github.com/kejuqu/febe...

创建两个应用 vite-reactvite-react-provider

  • vite-react-provider 暴露 Button 组件
  • vite-react 使用 vite-react-provider 应用暴露的 Button 组件

vite-react-provider 应用

js 复制代码
// vite.config.ts
import { defineConfig, type PluginOption } from "vite";
import react from "@vitejs/plugin-react";
import { federation } from "@module-federation/vite";

// https://vite.dev/config/
export default defineConfig({
  server: {
    port: 3006,
  },
  plugins: [
    react({
      babel: {
        plugins: [["babel-plugin-react-compiler"]],
      },
    }),
    federation({
      name: "remote",
      filename: "remoteEntry.js",
      // exposes 暴露 组件或者使用的工具函数
      exposes: {
        "./c-button": "./src/components/button.tsx",
      },
      shared: ["react", "react-dom"],
    }) as PluginOption[],
  ],
});

// src/components/button.tsx
export default function Button(props: React.ComponentProps<"button">) {
  return <button {...props}>button from remote</button>;
}

vite-react 使用 React.Lazy + dynamic import 加载远程模块

js 复制代码
// vite.config.ts
import { defineConfig } from "vite";
import { federation } from "@module-federation/vite";
import react from "@vitejs/plugin-react";

// https://vite.dev/config/
export default defineConfig({
  server: {
    port: 3005,
  },
  plugins: [
    react({
      babel: {
        plugins: [["babel-plugin-react-compiler"]],
      },
    }),
    federation({
      name: "customer",
      filename: "vite-react.js",
      // // exposes 暴露 组件或者使用的工具函数
      // exposes: {
      //   "./utils": "./src/utils.tsx",
      // },
      remotes: {
        remote: {
          type: "module",
          name: "remote",
          entry: "http://localhost:3006/remoteEntry.js",
          entryGlobalName: "remote",
          shareScope: "default",
        },
      },
      shared: ["react", "react-dom"],
    }),
  ],
});


// src/App.tsx
import React from "react";
import "./App.css";

function App() {
  const RemoteBtn = React.lazy(() => import("remote/c-button"));

  return (
    <>
      <React.Suspense fallback={<div>loading...</div>}>
        <RemoteBtn onClick={() => alert("clicked")} />
      </React.Suspense>
    </>
  );
}

export default App;

效果图

相关推荐
NiceCloud喜云7 小时前
Opus 4.8 的 Effort Control 怎么选:Low 到 Max 五档策略
android·java·大数据·前端·c++·python·spring
wordbaby7 小时前
React Native + RNOH:跨页面数据回传的最佳实践与避坑指南
前端·react native
丷丩7 小时前
MapLibre GL JS第22课:查看本地GeoJSON
前端·javascript·map·mapbox·maplibre gl js
Front思8 小时前
AI前端工程师需要具备能力+
前端·人工智能·ai
ZC跨境爬虫10 小时前
跟着 MDN 学CSS day_29:(掌握文本与字体样式的核心艺术)
前端·css·ui·html·tensorflow
李子琪。11 小时前
网络空间安全深度实战:CSRF 漏洞原理剖析与基于 Token 的纵深防御体系构建(全栈实验报告)
前端·安全·csrf
冰暮流星11 小时前
javascript之history对象介绍
前端·笔记
IT_陈寒12 小时前
Vite热更新失灵?你可能漏了这个配置
前端·人工智能·后端
丷丩12 小时前
MapLibre GL JS第19课:实时更新要素
前端·javascript·gis·map·mapbox·maplibre gl js
Mr.Daozhi12 小时前
RAG 进阶实战:跑通 Demo 后我连续翻了 6 次车,逐一修复才真正可用(含 Gradio Web 版)
前端·数据库·langchain·大模型·gradio·rag·科研工具