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;

效果图

相关推荐
无羡仙9 分钟前
从零构建 Vue 弹窗组件
前端·vue.js
源心锁1 小时前
👋 手搓 gzip 实现的文件分块压缩上传
前端·javascript
源心锁2 小时前
丧心病狂!在浏览器全天候记录用户行为排障
前端·架构
GIS之路2 小时前
GDAL 实现投影转换
前端
烛阴2 小时前
从“无”到“有”:手动实现一个 3D 渲染循环全过程
前端·webgl·three.js
BD_Marathon2 小时前
SpringBoot——辅助功能之切换web服务器
服务器·前端·spring boot
Kagol2 小时前
JavaScript 中的 sort 排序问题
前端·javascript
eason_fan3 小时前
Service Worker 缓存请求:前端性能优化的进阶利器
前端·性能优化
光影少年3 小时前
rn如何和原生进行通信,是单线程还是多线程,通信方式都有哪些
前端·react native·react.js·taro
好大哥呀3 小时前
Java Web的学习路径
java·前端·学习