Module Federation Basics
Module Federation Basics¶
Module Federation in Webpack 5 enables dynamic loading of remote code by allowing applications to share and consume modules as standalone components. This capability is central to micro frontend architectures, where multiple independent applications (or "micro frontends") need to collaborate while maintaining separation of concerns. By leveraging Webpack's module federation feature, developers can decouple applications, enabling features like hot updates, dynamic loading, and shared dependencies without monolithic bundling.
Key Concepts¶
- Container: The application that loads and executes remote modules. It acts as a host for federated modules and manages their lifecycle.
- Remote: A module or application that is shared and consumed by containers. It exposes its capabilities via a federation manifest.
- Shared Modules: Common dependencies or components that are shared across multiple containers. These are defined in the
sharedfield of the Webpack configuration. - Federation Manifest: A metadata file generated by Webpack that describes the remote modules available for loading. It includes details like module names, versions, and entry points.
How Module Federation Works¶
Webpack 5's module federation operates through two primary mechanisms: container and remote configurations.
-
Container Configuration:
A container application defines which remote modules it wants to load. It uses thecontainerplugin in its Webpack config to specify the shared modules and the remote applications it depends on. For example:// webpack.config.js (Container) const { ContainerPlugin } = require('webpack'); module.exports = { // ... plugins: [ new ContainerPlugin({ remotes: { 'remote-app': 'http://remote-app.com/remoteEntry.js', }, shared: { react: { singleton: true, requiredVersion: '^18.0.0' }, 'react-dom': { singleton: true, requiredVersion: '^18.0.0' }, }, }), ], }; -
Remote Configuration:
A remote application exposes its modules via theremoteplugin. It defines the entry points and shared dependencies it provides. For example:// webpack.config.js (Remote) const { RemoteModulePlugin } = require('webpack'); module.exports = { // ... plugins: [ new RemoteModulePlugin({ name: 'remote-app', filename: 'remoteEntry.js', remotes: { 'shared-lib': 'http://shared-lib.com/remoteEntry.js', }, shared: { 'lodash': { singleton: true }, }, }), ], };
When a container loads a remote module, Webpack dynamically fetches the remote entry file, resolves the module, and executes it in the container's context. This allows for runtime updates and modular composition.
Dynamic Loading via import()¶
Webpack 5 supports dynamic loading of remote modules using import() or require.ensure. For example:
// In a container application
import('remote-app').then((module) => {
const RemoteComponent = module.default;
// Render RemoteComponent in the UI
});
Diagram: Module Federation Architecture¶
+-------------------+ +-------------------+
| Container App | | Remote App |
| (e.g., Main UI) | | (e.g., Auth UI) |
+-------------------+ +-------------------+
| |
| |
v v
+-------------------+ +-------------------+
| Webpack Container |<----->| Webpack Remote |
| (loads remote) | | (exposes modules) |
+-------------------+ +-------------------+
| |
| |
v v
+-------------------+ +-------------------+
| Shared Modules |<----->| Shared Modules |
| (e.g., React) | | (e.g., Lodash) |
+-------------------+ +-------------------+
Key takeaways¶
- Module Federation in Webpack 5 enables dynamic loading of remote code via containers and remotes.
- Containers load and execute remote modules, while remotes expose shared capabilities.
- Shared modules are defined in the
sharedfield of Webpack configs to ensure consistency across applications. - Dynamic imports (
import()) allow lazy loading of federated modules, improving performance. - This architecture supports micro frontend patterns like hot updates and decoupled deployments.