Angular : Micro Frontend (Module Federation)

Sagarnath S
3 min readMay 21, 2023
Angular : Micro Frontend

Micro Frontends in Angular refer to the architectural approach of breaking down a large monolithic Angular application into smaller, self-contained and independent frontend modules. Each module represents a specific feature or functionality of the application and can be developed, deployed, and maintained separately.

Module Federation is a powerful feature provided by Webpack that enables the implementation of Micro Frontends in Angular. It allows you to dynamically load and integrate remote Angular modules (Micro Frontends) into a main application shell.

Module Federation handles the dynamic loading and sharing of modules, including their dependencies, at runtime. It enables applications to share code and resources, reducing duplication and improving the overall performance and development experience.

Here’s a step-by-step explanation of how you can implement Micro Frontends in Angular using Module Federation:

Step 1: Set up the Main Application Shell

  • Create an Angular project using the Angular CLI: ng new main-app.
  • Configure the project to use Module Federation. Install the necessary dependencies:
npm install @angular-architects/module-federation@next webpack@5 webpack-cli@4
  • Create a webpack.config.js file at the root of the project:
// webpack.config.js

const ModuleFederationPlugin = require('webpack').container.ModuleFederationPlugin;

module.exports = {
output: {
uniqueName: 'mainApp',
},
plugins: [
new ModuleFederationPlugin({
name: 'mainApp',
remotes: {},
shared: ['@angular/core', '@angular/common', '@angular/router'],
}),
],
};

Step 2: Create Micro Frontend Projects

  • Create individual Angular projects for each Micro Frontend. For example, create two projects: product-listing and shopping-cart:
ng generate application product-listing
ng generate application shopping-carts

Step 3: Configure Module Federation in Micro Frontends

  • In the webpack.config.js file of each Micro Frontend project, configure Module Federation:
// product-listing/webpack.config.js

const ModuleFederationPlugin = require('webpack').container.ModuleFederationPlugin;

module.exports = {
output: {
uniqueName: 'productListing',
publicPath: 'auto',
},
plugins: [
new ModuleFederationPlugin({
name: 'productListing',
filename: 'remoteEntry.js',
exposes: {
'./ProductListingModule': './src/app/product-listing/product-listing.module.ts',
},
shared: ['@angular/core', '@angular/common', '@angular/router'],
}),
],
};
// shopping-cart/webpack.config.js

const ModuleFederationPlugin = require('webpack').container.ModuleFederationPlugin;

module.exports = {
output: {
uniqueName: 'shoppingCart',
publicPath: 'auto',
},
plugins: [
new ModuleFederationPlugin({
name: 'shoppingCart',
filename: 'remoteEntry.js',
exposes: {
'./ShoppingCartModule': './src/app/shopping-cart/shopping-cart.module.ts',
},
shared: ['@angular/core', '@angular/common', '@angular/router'],
}),
],
};

Step 4: Build and Deploy Micro Frontends

  • Build each Micro Frontend project individually:
ng build product-listing
ng build shopping-cart
  • Deploy the built Micro Frontend projects to separate URLs, such as http://localhost:3001 and http://localhost:3002.

Step 5: Integrate Micro Frontends into the Main Application Shell

  • Update the webpack.config.js file of the main application shell to include the remote entries of the Micro Frontends:
// webpack.config.js

const ModuleFederationPlugin = require('webpack').container.ModuleFederationPlugin;

module.exports = {
output: {
uniqueName: 'mainApp',
},
plugins: [
new ModuleFederationPlugin({
name: 'mainApp',
remotes: {
productListing: 'productListing@http://localhost:3001/remoteEntry.js',
shoppingCart: 'shoppingCart@http://localhost:3002/remoteEntry.js',
},
shared: ['@angular/core', '@angular/common', '@angular/router'],
}),
],
};
  • Update the routing configuration in the app.module.ts file of the main application shell to lazy load the remote Angular modules:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule, Routes } from '@angular/router';
import { loadRemoteModule } from '@angular-architects/module-federation';

const routes: Routes = [
{ path: 'product-listing', loadChildren: () => loadRemoteModule('productListing', 'ProductListingModule') },
{ path: 'shopping-cart', loadChildren: () => loadRemoteModule('shoppingCart', 'ShoppingCartModule') },
];

@NgModule({
imports: [
BrowserModule,
RouterModule.forRoot(routes),
],
declarations: [],
bootstrap: [AppComponent],
})
export class AppModule { }

Step 6: Run the Main Application Shell

  • Build and run the main application shell:
ng build
ng serve
  • Access the main application shell at http://localhost:4200 and navigate to the Micro Frontends' routes (product-listing and shopping-cart). The remote Angular modules will be dynamically loaded and integrated into the main application shell.

By following these steps, you can implement Micro Frontends in Angular using Module Federation. Each Micro Frontend can be developed, deployed, and scaled independently, enabling a modular and decoupled architecture for your Angular application

In summary, Web Components focus on encapsulating UI components with reusable HTML, CSS, and JavaScript, while Module Federation focuses on dynamically loading and sharing modules between different applications at runtime. While they can be used together in a micro frontend architecture, they serve different purposes and address different aspects of web development.

Thank you for reading if you have any doubts. drop the message in comments.

Follow me on Medium or LinkedIn to read more about Angular and TS!

--

--

Sagarnath S

Software Development Engineer - I @CareStack || Web Developer || Angular || ASP.Net Core || C# || TypeScript || HTML || CSS