跨应用组件共享:使用模块联邦实现多框架协作

项目背景
在现代前端开发中,我们常常会遇到多个使用不同技术栈构建的前端项目,例如Vue、React等。这些项目之间可能存在共性功能或组件,但传统方式下需要为每个项目单独维护一套代码,导致重复开发和维护成本增加。本文将介绍如何通过模块联邦技术实现跨应用的组件共享,解决这一痛点问题。
实现方案
我们选择使用@originjs/vite-plugin-federation插件来实现这一目标。@originjs/vite-plugin-federation是一个基于Vite的模块联邦(Module Federation)插件,它允许在多个独立的Vite构建项目之间共享代码和依赖,实现微前端架构或跨应用的组件共享。
模块联邦的核心思想是将应用程序拆分为多个独立的构建块,这些构建块可以动态组合成一个完整的应用。每个构建块都可以作为提供者(Provider)或消费者(Consumer),或者同时扮演这两种角色。这种架构模式不仅实现了代码共享,还保持了应用的独立性和可扩展性。
实现步骤
-
在React项目中正常开发组件,使用ref抛出回调函数
首先,我们在React项目中开发需要共享的组件。以Button组件为例,确保组件已经完成开发并通过测试。
-
在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 }, });在配置中,我们通过
exposes选项指定要共享的组件,通过shared选项指定需要共享的依赖项,这样可以避免重复打包,减小最终包体积。 -
在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项目的配置中,我们通过
remotes选项指定要引用的远程应用及其入口地址。这里我们引用了之前配置的React应用。 -
在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>在Vue组件中,我们使用Vue 3的
defineAsyncComponent方法动态加载远程的React组件。通过Suspense组件处理加载状态,提供更好的用户体验。注意:远程组件的引用路径格式为
应用名/导出的组件路径,与我们在React项目的vite.config.js中通过exposes定义的路径保持一致。
注意事项
- 确保远程应用的入口地址可访问,在生产环境中需要使用正确的URL
- 合理配置共享依赖,避免重复打包或依赖冲突
- 处理组件加载状态,提供良好的用户体验
- 注意跨框架组件的样式隔离问题
- 考虑组件版本兼容性,特别是共享依赖的版本
总结
通过模块联邦技术,我们成功实现了不同框架(Vue、React)之间的组件共享,有效提高了代码复用率并降低了维护成本。这种架构模式特别适合大型企业级应用或需要渐进式迁移的场景,为微前端架构的实现提供了强有力的技术支持。