Concept
What is Module Federation?
Traditional code sharing involves compiling all dependencies into a single bundle at build time. When a shared utility changes, you must rebuild and redeploy the entire application.
Module Federation (introduced in Webpack 5 and supported by Rspack/Vite) enables runtime compilation. An application can act as a Host (loading code), a Remote (exposing code), or both simultaneously:
- Host: Dynamically imports code at runtime.
- Remote: Exposes code modules (components, functions, hooks) via a global entry file (
remoteEntry.js).
Isolated Loading Lifecycle
Here is how a Host dynamically resolves a Remote component at runtime:
Federation Config Controls (Break the Micro Frontend)Simulate Real Outages
Host (React 19.0.0) rejected Remote (React 18.2.0). Remote failed to mount, but local <MFEErrorBoundary> prevented the Host App from crashing!
Unsatisfied version: Shared module 'react' version 19.0.0 does not satisfy requiredVersion 18.2.0.
Shared Dependency Management
If both the Host and Remote use React, downloading React twice would increase load times and break React context states. Module Federation allows containers to share dependencies:
Federation Config Controls (Break the Micro Frontend)Simulate Real Outages
Host (React 19.0.0) rejected Remote (React 18.2.0). Remote failed to mount, but local <MFEErrorBoundary> prevented the Host App from crashing!
Unsatisfied version: Shared module 'react' version 19.0.0 does not satisfy requiredVersion 18.2.0.
If the version rules match, the Remote instantly reuses the Host's React instance, fetching 0 bytes for the library code.
Common Mistakes
1. Version collisions on singleton dependencies
React must be a singleton in memory. If Host runs React 19 and Remote configures React as a non-singleton, the remote mounts its own React package, leading to console errors: Hooks can only be called inside the body of a function component. Always set { singleton: true } for React/React-DOM in shared configs.
2. Assuming remotes are always online
If the server hosting a Remote container crashes, the Host fails to resolve remoteEntry.js and crashes. Always wrap dynamic imports in React ErrorBoundary and Suspense boundaries:
<ErrorBoundary fallback={<ErrorCard />}>
<Suspense fallback={<Spinner />}>
<RemoteButton />
</Suspense>
</ErrorBoundary>Best Practices
- Strict SemVer contracts: Ensure all shared dependencies declare
requiredVersionto prevent loading incompatible library versions at runtime. - Use Error Boundaries: Safeguard the host app from crashing when a remote server goes offline.
- Dynamic remote URLs: Instead of hardcoding remote URLs in Webpack configs, resolve them at runtime via custom loaders.
