Module Federation may encounter various issues in practical applications. Here are common problems and their solutions:
1. Version Conflict Issues
Problem Description: Multiple applications use different versions of shared dependencies, causing runtime errors.
Solution:
javascript// Use strictVersion and requiredVersion to control versions shared: { react: { singleton: true, requiredVersion: '^17.0.0', strictVersion: false, // Allow minor version differences version: deps.react } } // Or use the resolutions field in package.json to unify versions { "resolutions": { "react": "^17.0.2", "react-dom": "^17.0.2" } }
2. Module Loading Failures
Problem Description: Remote modules fail to load, causing the application to crash.
Solution:
javascript// Add error boundaries and fallback strategies class ErrorBoundary extends React.Component { state = { hasError: false } static getDerivedStateFromError(error) { return { hasError: true } } render() { if (this.state.hasError) { return this.props.fallback || <FallbackComponent /> } return this.props.children } } // Use Suspense and error handling const RemoteComponent = React.lazy(() => import('remoteApp/Component').catch(() => import('./LocalFallback') ) ) function App() { return ( <ErrorBoundary fallback={<LocalFallback />}> <Suspense fallback={<Loading />}> <RemoteComponent /> </Suspense> </ErrorBoundary> ) }
3. Development Environment CORS Issues
Problem Description: During local development, remote applications on different ports cannot be loaded.
Solution:
javascript// Configure devServer in webpack.config.js devServer: { port: 3000, headers: { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS', 'Access-Control-Allow-Headers': 'X-Requested-With, content-type, Authorization' } } // Or use proxy devServer: { port: 3000, proxy: { '/remote': { target: 'http://localhost:3001', changeOrigin: true, pathRewrite: { '^/remote': '' } } } }
4. Style Isolation Issues
Problem Description: Styles from remote modules affect the main application or other remote modules.
Solution:
javascript// Use CSS Modules import styles from './Button.module.css' // Or use CSS-in-JS import styled from 'styled-components' const Button = styled.button` /* Styles automatically isolated */ ` // Or use Shadow DOM class ShadowComponent extends HTMLElement { constructor() { super() this.attachShadow({ mode: 'open' }) } connectedCallback() { this.shadowRoot.innerHTML = ` <style> button { color: red; } </style> <button>Shadow Button</button> ` } }
5. State Management Issues
Problem Description: State between multiple applications cannot be shared.
Solution:
javascript// Use shared state management library // Remote application export { createStore } from './store' // Host application import { createStore } from 'remoteApp/store' const store = createStore() // Or use event bus const eventBus = { listeners: {}, on(event, callback) { if (!this.listeners[event]) { this.listeners[event] = [] } this.listeners[event].push(callback) }, emit(event, data) { if (this.listeners[event]) { this.listeners[event].forEach(cb => cb(data)) } } }
6. Route Conflict Issues
Problem Description: Route configurations from multiple applications conflict.
Solution:
javascript// Use route prefixes const routes = [ { path: '/dashboard/*', component: React.lazy(() => import('dashboardApp/App')) }, { path: '/settings/*', component: React.lazy(() => import('settingsApp/App')) } ] // Or use route guards const ProtectedRoute = ({ children, ...rest }) => { const isAuthenticated = useAuth() return ( <Route {...rest}> {isAuthenticated ? children : <Redirect to="/login" />} </Route> ) }
7. Type Definition Issues
Problem Description: TypeScript cannot recognize types from remote modules.
Solution:
javascript// Create type declaration file types.d.ts declare module 'remoteApp/*' { const value: any export default value } // Or use type exports // Remote application export interface ButtonProps { label: string onClick: () => void } // Host application import type { ButtonProps } from 'remoteApp/types'
8. Large Build Artifacts
Problem Description: remoteEntry.js or module files are too large, affecting loading speed.
Solution:
javascript// Use code splitting optimization: { splitChunks: { chunks: 'all', cacheGroups: { vendor: { test: /[\\/]node_modules[\\/]/, name: 'vendors', priority: 10 }, common: { name: 'common', minChunks: 2, priority: 5 } } } } // Compress build artifacts optimization: { minimize: true, minimizer: [ new TerserPlugin({ terserOptions: { compress: { drop_console: true } } }) ] }
Through these solutions, you can effectively address various issues encountered when using Module Federation in practical applications.