Module Federation 可以与多种前端框架配合使用,以下是各框架的具体实现方案:
1. React + Module Federation
基础配置:
javascript// webpack.config.js const { ModuleFederationPlugin } = require('webpack').container module.exports = { // ...其他配置 plugins: [ new ModuleFederationPlugin({ name: 'reactApp', filename: 'remoteEntry.js', exposes: { './Button': './src/Button', './Header': './src/Header' }, shared: { react: { singleton: true, eager: true }, 'react-dom': { singleton: true, eager: true } } }) ] }
使用远程组件:
javascriptimport React, { Suspense } from 'react' const RemoteButton = React.lazy(() => import('remoteApp/Button')) function App() { return ( <Suspense fallback={<div>Loading...</div>}> <RemoteButton label="Click me" /> </Suspense> ) }
2. Vue 3 + Module Federation
基础配置:
javascript// vue.config.js const { defineConfig } = require('@vue/cli-service') const ModuleFederationPlugin = require('webpack').container.ModuleFederationPlugin module.exports = defineConfig({ configureWebpack: { plugins: [ new ModuleFederationPlugin({ name: 'vueApp', filename: 'remoteEntry.js', exposes: { './Button': './src/components/Button.vue' }, shared: { vue: { singleton: true, eager: true } } }) ] } })
使用远程组件:
javascript<template> <div> <Suspense> <template #default> <RemoteButton :text="buttonText" /> </template> <template #fallback> <div>Loading...</div> </template> </Suspense> </div> </template> <script> import { defineAsyncComponent } from 'vue' export default { components: { RemoteButton: defineAsyncComponent(() => import('remoteApp/Button') ) }, data() { return { buttonText: 'Click me' } } } </script>
3. Angular + Module Federation
基础配置:
javascript// webpack.config.js const ModuleFederationPlugin = require('webpack').container.ModuleFederationPlugin module.exports = { plugins: [ new ModuleFederationPlugin({ name: 'angularApp', filename: 'remoteEntry.js', exposes: { './ButtonComponent': './src/app/button/button.component.ts' }, shared: { '@angular/core': { singleton: true }, '@angular/common': { singleton: true } } }) ] }
使用远程组件:
typescriptimport { Component, NgModule } from '@angular/core' import { BrowserModule } from '@angular/platform-browser' @Component({ selector: 'app-root', template: ` <ng-container *ngIf="remoteButton"> <ng-container *ngComponentOutlet="remoteButton"></ng-container> </ng-container> ` }) export class AppComponent { remoteButton: any async ngOnInit() { const module = await import('remoteApp/ButtonComponent') this.remoteButton = module.ButtonComponent } }
4. Svelte + Module Federation
基础配置:
javascript// rollup.config.js import moduleFederation from '@module-federation/rollup-plugin' export default { plugins: [ moduleFederation({ name: 'svelteApp', filename: 'remoteEntry.js', exposes: { './Button': './src/Button.svelte' }, shared: { svelte: { singleton: true } } }) ] }
使用远程组件:
javascript<script> import { onMount } from 'svelte' let RemoteButton onMount(async () => { const module = await import('remoteApp/Button') RemoteButton = module.default }) </script> {#if RemoteButton} <svelte:component this={RemoteButton} text="Click me" /> {/if}
5. 框架间互操作
React 使用 Vue 组件:
javascriptimport React from 'react' const VueComponentWrapper = React.lazy(() => import('vueApp/Button') ) function ReactApp() { return ( <Suspense fallback={<div>Loading Vue component...</div>}> <VueComponentWrapper /> </Suspense> ) }
Vue 使用 React 组件:
javascript<template> <div> <ReactComponentWrapper /> </div> </template> <script> import { defineAsyncComponent, onMounted } from 'vue' export default { components: { ReactComponentWrapper: defineAsyncComponent(() => import('reactApp/Button') ) } } </script>
最佳实践:
- 统一依赖版本:确保所有应用使用相同版本的共享依赖
- 类型安全:使用 TypeScript 或类型声明文件确保类型安全
- 错误处理:为远程组件添加错误边界和降级方案
- 性能优化:使用懒加载和代码分割优化性能
- 样式隔离:使用 CSS Modules 或 CSS-in-JS 避免样式冲突
通过以上配置,Module Federation 可以与各种前端框架无缝集成,实现跨框架的模块共享。