跨应用的组件共享

项目背景
有多个不同框架搭建的前端项目,例如vue、react,现两个项目之间有共性,但又不想同时维护两套代码,例如实现一个组件可以共用
实现方案
使用@originjs/vite-plugin-federation插件 @originjs/vite-plugin-federation 是一个基于 Vite 的 模块联邦(Module Federation) 插件,它允许你在多个独立的 Vite 构建项目之间共享代码和依赖,实现微前端架构或跨应用的组件共享。
实现步骤
- 在react项目中正常开发组件,使用ref抛出回调函数
- 在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
},
});
- 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",
},
});
- 在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>