A Guide to Module Federation and Micro-Frontend Applications in Angular — Part 2
1) Create the Host Application
ng new host
2) Create the Micro-Frontend Applications
ng new teams
ng new calendar
3) Upgrade Angular Versions of Each Application
ng update @angular/cli @angular/core --allow-dirty
4) Install PrimeNG for All Applications For Styling (Optional)
npm i primeng@latest
npm i primeicons
src/style.css
:
@import "primeng/resources/themes/bootstrap4-light-blue/theme.css";
@import "primeng/resources/primeng.css";
@import "primeicons/primeicons.css";
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
font-family: var(--font-family);
}
5) Migrate the Existing Angular Projects to Standalone
Run the command below and select “Convert all components, directives and pipes to standalone
”:
ng g @angular/core:standalone
Run the command below and select “Remove unnecessary NgModule classes
”:
ng g @angular/core:standalone
Run the command below and select “Bootstrap the project using standalone APIs
”:
ng g @angular/core:standalone
6) Bootstrapping the Apps with Standalone Components
Delete the AppComponent and create your own Standalone Components for all projects:
ng g c host --standalone
ng g c teams --standalone
ng g c calendar --standalone
Create route files for all projects (The route list will be provided during the Module Federation setup):
host/src/app/routes/host.routes.ts
:
export const HOST_ROUTES: Routes = [];
calendar/src/app/routes/calendar.routes.ts
:
export const CALENDAR_ROUTES: Routes = [];
teams/src/app/routes/teams.routes.ts
:
export const TEAMS_ROUTES: Routes = [];
Update the index.html to specify the application’s entry point for all projects:
host/src/index.html
:
<body>
<app-host></app-host>
</body>
calendar/src/index.html
:
<body>
<app-calendar></app-calendar>
</body>
teams/src/index.html
:
<body>
<app-teams></app-teams>
</body>
Update the main.ts to migrate to BootstrapApplication:
host/src/main.ts
:
import { importProvidersFrom } from "@angular/core";
import { bootstrapApplication, BrowserModule } from "@angular/platform-browser";
import { provideRouter, RouterModule, withComponentInputBinding } from "@angular/router";
bootstrapApplication(HostComponent, {
providers: [
importProvidersFrom(
BrowserModule,
RouterModule,
),
provideRouter(
HOST_ROUTES,
withComponentInputBinding(), // For Input Binding (Requires Angular Version 16+)
)
],
});
calendar/src/main.ts
:
import { importProvidersFrom } from "@angular/core";
import { bootstrapApplication, BrowserModule } from "@angular/platform-browser";
import { provideRouter, RouterModule, withComponentInputBinding } from "@angular/router";
bootstrapApplication(CalendarComponent, {
providers: [
importProvidersFrom(
BrowserModule,
RouterModule,
),
provideRouter(
CALENDAR_ROUTES,
withComponentInputBinding(), // For Input Binding (Requires Angular Version 16+)
)
],
});
teams/src/main.ts
:
import { importProvidersFrom } from "@angular/core";
import { bootstrapApplication, BrowserModule } from "@angular/platform-browser";
import { provideRouter, RouterModule, withComponentInputBinding } from "@angular/router";
bootstrapApplication(TeamsComponent, {
providers: [
importProvidersFrom(
BrowserModule,
RouterModule,
),
provideRouter(
TEAMS_ROUTES,
withComponentInputBinding(), // For Input Binding (Requires Angular Version 16+)
)
],
});
7) Module Federation Setup
Install dependencies for Module Federation:
npm i @angular-architects/module-federation
Migrate micro-frontend apps to Module Federation:
ng add @angular-architects/module-federation --project calendar --port 4201 --type remote
ng add @angular-architects/module-federation --project teams --port 4202 --type remote
Migrate the host app to Module Federation:
ng add @angular-architects/module-federation --project host --port 4200 --type dynamic-host
As a result:
- Main.ts files will have been moved to the bootstrap.ts. Check all projects and fix if AppComponent is used instead of Standalone Components.
- Index.html files may have changed. Check all projects and fix if AppComponent is used instead of Standalone Components.
- In the host project, you can manage micro-frontends and their ports through the host/src/assets/mf.manifest.json file.
Declare the micro-frontend endpoints in the Host App:
host/src/assets/mf.manifest.json
:
{
"calendar": "http://localhost:4201/remoteEntry.js",
"teams": "http://localhost:4202/remoteEntry.js"
}
Expose route files of the micro-frontends via their webpack.config.js:
calendar/webpack.config.js
:
exposes: {
'./routes': './src/app/routes/calendar.routes.ts'
}
teams/webpack.config.js
:
exposes: {
'./routes': './src/app/routes/teams.routes.ts'
}
Fill in the contents of the Route files in each project:
calendar/src/app/routes/calendar.routes.ts
:
export const CALENDAR_ROUTES: Routes = [
{ path: '', redirectTo: 'menu', pathMatch: "full" },
{
path: 'menu',
loadComponent: () => import('../calendar.component')
.then(c => c.CalendarComponent)
},
{ path: '**', redirectTo: 'menu' },
];
teams/src/app/routes/teams.routes.ts
:
export const TEAMS_ROUTES: Routes = [
{ path: '', redirectTo: 'menu', pathMatch: "full" },
{
path: 'menu',
loadComponent: () => import('../teams.component')
.then(c => c.TeamsComponent)
},
{ path: '**', redirectTo: 'menu' },
];
host/src/app/routes/host.routes.ts
:
import { loadRemoteModule } from '@angular-architects/module-federation';
export const HOST_ROUTES: Routes = [
{ path: '', redirectTo: "calendar", pathMatch: "full" },
{
path: 'calendar',
loadChildren: () => loadRemoteModule({
type: 'manifest',
remoteName: 'calendar', // The name that is written in assets/mf.manifest.json
exposedModule: './routes'
}).then(r => r.CALENDAR_ROUTES),
},
{
path: 'teams',
loadChildren: () => loadRemoteModule({
type: 'manifest',
remoteName: 'teams', // The name that is written in assets/mf.manifest.json
exposedModule: './routes'
}).then(r => r.TEAMS_ROUTES),
},
{ path: "**", redirectTo: 'calendar', pathMatch: "full" }
];
8) Run the Apps
Run the Micro-Frontend Applications:
ng serve
Run the Host Application:
ng serve
9) Application Screenshots
Thank you for reading, and happy coding! :)
Project Link:
https://github.com/hurkanugur/Micro-Frontends-and-Module-Federation/tree/main