This guide explains how to integrate Module Federation with Angular CLI. The @angular-architects/module-federation
plugin is used to assist with this integration.
@angular-architects/module-federation
plugin.To start, configure the Angular CLI to use Module Federation during the build phase. A custom builder is needed to unlock Module Federation's potential.
The @angular-architects/module-federation
package provides this custom builder.
Use the ng add command to incorporate it into your projects:
The --type
argument, introduced in version 14.3, ensures that only the necessary configuration is generated.
The Shell (Host) is crucial for Module Federation integration.
This section configures the Shell to support lazy-loading of a FlightModule
through routing.
Start by defining the application routes, specifying a lazy-loaded FlightModule
using a virtual path:
In this configuration, the path 'mfe1/Module'
is a virtual representation, indicating it doesn't physically exist within the Shell application. Instead, it's a reference to a module in a separate project.
Create a type definition for the virtual path:
This helps the TypeScript compiler understand the virtual path.
Instruct Webpack to resolve all paths prefixed with mfe1
to a remote project. This is done in the webpack.config.js
file:
In the remotes
section, the path mfe1
is mapped to the remote micro-frontend's entry point. This entry point, generated by Webpack, contains essential information for interacting with the micro-frontend.
For development, hardcoding the remote entry's URL is enough. However, a dynamic approach is necessary for production. The concept of dynamic remotes is further explored in a dedicated documentation page on Dynamic Remotes.
shared
property specifies the npm packages to be shared between the Shell and the micro-frontend(s). Using the shareAll
helper method, all dependencies listed in your package.json
are shared. While this facilitates a quick setup, it may lead to an excessive number of shared dependencies, which could be a concern for optimization.singleton: true
and strictVersion: true
settings instructs Webpack to throw a runtime error if there is a version mismatch between the Shell and the micro-frontend(s). Changing strictVersion
to false
would instead result in a runtime warning.requiredVersion: 'auto'
option, provided by the @angular-architects/module-federation
plugin, automatically determines the version from your package.json
, helping to prevent version-related issues.The Micro-frontend, also known as the Remote in Module Federation, has a structure similar to a standard Angular app. It has specific routes in the AppModule
and a FlightsModule
for flight-related tasks. This section explains how to smoothly load the FlightsModule
into the Shell (Host).
Establish the basic routes within the AppModule
:
This simple routing setup navigates to a HomeComponent
when the application is accessed.
Create a FlightsModule
to handle flight-related operations:
This module contains a route to a FlightsSearchComponent
defined as follows:
To enable the loading of FlightsModule
into the Shell, expose it through the Remote's Webpack configuration:
In this configuration:
name
property identifies the micro-frontend as mfe1
.exposes
property signifies the exposure of FlightsModule
under the public name Module
, allowing its consumption by the Shell.shared
property lists the libraries to be shared with the Shell, using the shareAll
method to share all dependencies found in your package.json
. The singleton: true
and strictVersion: true
properties ensure that a single version of shared libraries is used, and a runtime error is triggered in case of version incompatibility, respectively.Having set up the Shell (Host) and Micro-frontend (Remote), it's time to test the configuration to ensure the seamless integration of Module Federation.
To start the Shell and Micro-frontend, use the following commands:
Navigate to the Flights section in the Shell to see the Micro-frontend being dynamically loaded.
The plugin installs an npm script run:all
during the ng-add
and init
schematics, allowing for simultaneous serving of all applications:
The initial setup with shareAll
is simple and functional, but it can result in the creation of unnecessarily large shared bundles.
To manage shared dependencies more effectively, consider switching from shareAll
to using the share
helper. This provides finer control over which dependencies are shared:
In this configuration, the share
helper allows for explicit sharing of selected packages, enabling a more optimized bundle sharing and potentially reducing load times.