Architecture design for Module Federation in large-scale enterprise applications requires considering multiple aspects. Here is a detailed architecture solution:
1. Multi-Layer Architecture Design
Three-Layer Architecture Pattern:
shell┌─────────────────────────────────────────┐ │ Host Layer (主应用层) │ │ - Route Management │ │ - Global State Management │ │ - User Authentication & Authorization │ └──────────────┬──────────────────────────┘ │ ┌──────────────▼──────────────────────────┐ │ Business Layer (业务模块层) │ │ - Order Module │ │ - User Module │ │ - Payment Module │ └──────────────┬──────────────────────────┘ │ ┌──────────────▼──────────────────────────┐ │ Component Layer (基础组件层) │ │ - UI Component Library │ │ - Utility Function Library │ │ - Business Components │ └─────────────────────────────────────────┘
2. Module Division Strategy
Division by Business Domain:
javascript// Order Module new ModuleFederationPlugin({ name: 'orderModule', filename: 'remoteEntry.js', exposes: { './OrderList': './src/OrderList', './OrderDetail': './src/OrderDetail', './OrderCreate': './src/OrderCreate', './OrderAPI': './src/api/order' }, shared: { react: { singleton: true }, 'react-dom': { singleton: true }, '@company/ui-components': { singleton: true }, '@company/utils': { singleton: true } } }) // User Module new ModuleFederationPlugin({ name: 'userModule', filename: 'remoteEntry.js', exposes: { './UserProfile': './src/UserProfile', './UserSettings': './src/UserSettings', './UserAPI': './src/api/user' }, shared: { react: { singleton: true }, 'react-dom': { singleton: true }, '@company/ui-components': { singleton: true } } })
Division by Functional Layer:
javascript// Base Component Library new ModuleFederationPlugin({ name: 'componentLibrary', filename: 'remoteEntry.js', exposes: { './Button': './src/components/Button', './Modal': './src/components/Modal', './Table': './src/components/Table', './Form': './src/components/Form' }, shared: { react: { singleton: true }, 'react-dom': { singleton: true }, 'styled-components': { singleton: true } } }) // Utility Library new ModuleFederationPlugin({ name: 'utilityLibrary', filename: 'remoteEntry.js', exposes: { './request': './src/utils/request', './storage': './src/utils/storage', './validation': './src/utils/validation', './format': './src/utils/format' }, shared: {} })
3. State Management Architecture
Centralized State Management:
javascript// Main Application State Management import { createStore } from 'redux' import { Provider } from 'react-redux' const rootReducer = combineReducers({ auth: authReducer, theme: themeReducer, // Remote module reducers will be registered at runtime modules: (state = {}, action) => { // Dynamically registered module reducers return moduleReducers.reduce((acc, reducer) => { return reducer(acc, action) }, state) } }) const store = createStore(rootReducer) // Remote module registers reducer export const registerModuleReducer = (name, reducer) => { moduleReducers.push(reducer) store.replaceReducer(createRootReducer()) }
Distributed State Management:
javascript// Use event bus for cross-module communication class EventBus { constructor() { this.events = {} } on(event, callback) { if (!this.events[event]) { this.events[event] = [] } this.events[event].push(callback) } emit(event, data) { if (this.events[event]) { this.events[event].forEach(callback => callback(data)) } } off(event, callback) { if (this.events[event]) { this.events[event] = this.events[event].filter(cb => cb !== callback) } } } export const eventBus = new EventBus() // Remote modules use event bus import { eventBus } from '@company/event-bus' // Publish event eventBus.emit('order:created', { orderId: 123 }) // Subscribe to event eventBus.on('order:created', (data) => { console.log('Order created:', data) })
4. Routing Architecture Design
Main Application Routing Configuration:
javascriptimport { BrowserRouter, Routes, Route } from 'react-router-dom' const routes = [ { path: '/orders', component: React.lazy(() => import('orderModule/OrderList')) }, { path: '/orders/:id', component: React.lazy(() => import('orderModule/OrderDetail')) }, { path: '/users', component: React.lazy(() => import('userModule/UserProfile')) }, { path: '/settings', component: React.lazy(() => import('userModule/UserSettings')) } ] function App() { return ( <BrowserRouter> <Suspense fallback={<Loading />}> <Routes> {routes.map((route, index) => ( <Route key={index} path={route.path} element={<route.component />} /> ))} </Routes> </Suspense> </BrowserRouter> ) }
Dynamic Route Loading:
javascript// Route configuration file const routeConfig = { '/orders': { module: 'orderModule', component: 'OrderList', permissions: ['orders:read'] }, '/orders/create': { module: 'orderModule', component: 'OrderCreate', permissions: ['orders:create'] } } // Dynamic route loader const loadRoute = async (path) => { const config = routeConfig[path] if (!config) return null const { module, component } = config const Component = await import(`${module}/${component}`) return Component.default }
5. Dependency Management Strategy
Unified Dependency Versions:
json// Root package.json { "name": "monorepo", "private": true, "workspaces": [ "packages/*" ], "scripts": { "sync-deps": "sync-dependencies" }, "devDependencies": { "sync-dependencies": "^1.0.0" } }
Dependency Synchronization Script:
javascript// scripts/sync-dependencies.js const fs = require('fs') const path = require('path') const sharedDependencies = { react: '^17.0.2', 'react-dom': '^17.0.2', 'react-router-dom': '^6.0.0', 'styled-components': '^5.3.0' } const packagesDir = path.join(__dirname, '../packages') fs.readdirSync(packagesDir).forEach(pkgName => { const pkgPath = path.join(packagesDir, pkgName, 'package.json') if (fs.existsSync(pkgPath)) { const pkg = require(pkgPath) pkg.dependencies = { ...pkg.dependencies, ...sharedDependencies } fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2)) } })
6. Performance Optimization Architecture
Preload Strategy:
javascript// Intelligent preloader class PreloadManager { constructor() { this.preloadedModules = new Set() this.preloadQueue = [] } preload(moduleName) { if (this.preloadedModules.has(moduleName)) return this.preloadQueue.push(moduleName) this.processQueue() } async processQueue() { if (this.isProcessing) return this.isProcessing = true while (this.preloadQueue.length > 0) { const moduleName = this.preloadQueue.shift() try { await import(moduleName) this.preloadedModules.add(moduleName) } catch (error) { console.error(`Failed to preload ${moduleName}:`, error) } } this.isProcessing = false } } export const preloadManager = new PreloadManager() // Usage example preloadManager.preload('orderModule/OrderList')
Cache Strategy:
javascript// Service Worker cache configuration const CACHE_NAME = 'module-federation-v1' const CACHE_URLS = [ '/remoteEntry.js', '/main.js', '/vendor.js' ] self.addEventListener('install', (event) => { event.waitUntil( caches.open(CACHE_NAME).then((cache) => { return cache.addAll(CACHE_URLS) }) ) }) self.addEventListener('fetch', (event) => { event.respondWith( caches.match(event.request).then((response) => { return response || fetch(event.request) }) ) })
7. Monitoring and Logging Architecture
Module Loading Monitoring:
javascript// Module loading tracker class ModuleTracker { constructor() { this.loadTimes = new Map() this.errorCounts = new Map() } track(moduleName, status, duration) { const key = `${moduleName}_${status}` const count = this.errorCounts.get(key) || 0 this.errorCounts.set(key, count + 1) if (status === 'success') { this.loadTimes.set(moduleName, duration) } // Send to monitoring system this.sendToMonitoring({ module: moduleName, status, duration, timestamp: Date.now() }) } sendToMonitoring(data) { // Send to backend monitoring system fetch('/api/monitoring/modules', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }).catch(console.error) } } export const moduleTracker = new ModuleTracker()
8. Disaster Recovery Architecture
Fallback Strategy:
javascript// Module fallback manager class FallbackManager { constructor() { this.fallbacks = new Map() } register(moduleName, fallbackComponent) { this.fallbacks.set(moduleName, fallbackComponent) } async loadWithFallback(moduleName) { try { const module = await import(moduleName) return module.default } catch (error) { console.error(`Failed to load ${moduleName}, using fallback`) const fallback = this.fallbacks.get(moduleName) if (fallback) { return fallback } throw error } } } export const fallbackManager = new FallbackManager() // Register fallback components fallbackManager.register('orderModule/OrderList', LocalOrderList)
Through this architecture design, you can build a scalable, high-performance, and maintainable enterprise-level Module Federation application.