J'Blog

跨应用的组件共享

跨应用的组件共享

项目背景

有多个不同框架搭建的前端项目,例如vue、react,现两个项目之间有共性,但又不想同时维护两套代码,例如实现一个组件可以共用

实现方案

使用@originjs/vite-plugin-federation插件 @originjs/vite-plugin-federation 是一个基于 Vite 的 模块联邦(Module Federation) 插件,它允许你在多个独立的 Vite 构建项目之间共享代码和依赖,实现微前端架构或跨应用的组件共享。

实现步骤

  1. 在react项目中正常开发组件,使用ref抛出回调函数
  2. 在vite.config文件中导出组件
// vite.config.js
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import federation from "@originjs/vite-plugin-federation";

export default defineConfig({
  plugins: [
    react(),
    federation({
      name: "react_app", // 应用名称(唯一标识)
      filename: "remoteEntry.js", // 远程入口文件
      exposes: {
        // 导出的组件
        "./ReactButton": "./src/components/Button.jsx",
      },
      shared: ["react", "react-dom"], // 共享依赖
    }),
  ],
  build: {
    target: "esnext", // 需要支持动态 import
  },
});
  1. vue项目中引入组件
// vite.config.js
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import federation from "@originjs/vite-plugin-federation";

export default defineConfig({
  plugins: [
    vue(),
    federation({
      name: "vue_app",
      remotes: {
        // 引用远程 React 项目
        react_app: "http://localhost:5001/assets/remoteEntry.js",
      },
      shared: ["vue"], // 共享依赖
    }),
  ],
  build: {
    target: "esnext",
  },
});
  1. 在vue中使用react
<template>
  <div>
    <h1>Vue App</h1>
    <Suspense>
      <template #default>
        <ReactButton />
      </template>
      <template #fallback>
        Loading React Button...
      </template>
    </Suspense>
  </div>
</template>

<script>
import { defineAsyncComponent } from "vue";

export default {
  components: {
    // 动态加载远程 React 组件
    ReactButton: defineAsyncComponent(() =>
      import("react_app/ReactButton").then((mod) => mod.default)
    ),
  },
};
</script>