Related Resources

Our Services

You May Also Like

How To Build Micro Frontend With Micro Federation in Angular?

Nimit Shah

Jan 03, 2023

4 min readLast Updated Aug 22, 2023

Micro Frontends are a way to build and deliver a large application as a composition of small, independent applications. This approach enables teams to work on their own codebases and deliver new features faster, while also making it easier to scale development.

Module Federation is a way to implement Micro Frontends in the Angular ecosystem. It allows multiple Angular applications to share a common set of libraries and enables them to communicate with each other using a shared API.

Benefits of Building Micro Frontend with Module Federation

The benefits of this include:

  1. Improved scalability: By breaking the frontend application into smaller units, it becomes easier to scale individual parts of the application independently. This can be particularly useful if different parts of the application have different scaling needs.
  2. Enhanced maintainability: Decomposing the frontend application into smaller, self-contained units make it easier to understand and maintain the codebase. This can be especially useful in large organizations where multiple teams are working on the same codebase.
  3. Faster deployment: Because microfrontends and module federation allows for independent deployment of different parts of the frontend application, it becomes possible to deploy changes to production more quickly.
  4. Improved code reuse: Decomposing the frontend application into smaller units makes it easier to reuse code across different parts of the application.
  5. Better team autonomy: By allowing teams to work on self-contained units of the frontend application, microfrontends and module federation can improve team autonomy and reduce dependencies between teams.

Steps to Create Micro Frontend

Let's get started and create a small microfrontend.

Before starting please make sure you have the following prerequisites

  • Have some basic knowledge of Angular and Angular CLI.
  • A system with NodeJs and Angular CLI already installed
  • Angular and Angular CLI needs to be atleast 14 or higher

Angular's Module Federation team has conveniently provided a starter kit for this. So let's first clone their repo and download the dependencies with the following commands

git clone https://github.com/manfredsteyer/module-federation-plugin-example.git --branch starter
cd module-federation-plugin-example
npm i

In the project, if you have already noticed there are 2 folders in the project folder. One is shell and the other is mfe1. In this example, the 'shell' will be the host while mfe1 will be the microfrontend

Inside mfe1 there is a flights module at projects/mfe1/src/app/flights that we will be going to load through the shell. You can individually serve them using ng serve shell -o and ng serve mfe1 -o to serve the application individually.

Now, let's activate and configure module federation:

Install @angular-architects/module-federation into them:

ng add @angular-architects/module-federation --project shell --type host --port 4200
ng add @angular-architects/module-federation --project mfe1 --type remote --port 4201


This activates module federation, assigns a port for ng serve and generates the skeleton of a module federation configuration.

Now, let's start configuring the microfrontend. Open the file projects\mfe1\webpack.config.js. This is where it is defined what you are exposing to the host.
By default, you will be exposing the app.component.ts file. Instead, let's expose the Flights module. So replace the entire exposes object with

exposes: {
	'./Module': './projects/mfe1/src/app/flights/flights.module.ts',
},

This is basically saying to expose the flights module to any hosts that use mfe1.

Similarly, if you open the shell’s config file ‘projects\shell\webpack.config.js’ you will notice instead of exposes there is a remotes object. This basically says to the Host that there is a remote mfe1 which can be referenced in its router.

Make sure that mfe1’s port is 4201 instead of 4200

remotes: {
	mfe1: 'http://localhost:4201/remoteEntry.js',
},

This references the separately compiled and deployed mfe1 project.

Now let's load reference the microfrontend in the shell’s router. Open projects\shell\src\app\app.routes.ts and add a route to the Micro Frontend

{
	path: 'flights',
	loadChildren: () => import('mfe1/Module').then(m => m.FlightsModule)
},

Please note that the imported URL consists of the names defined in the configuration files above. So depending on what you assign in expose object the import URL changes import('mfe1/Module').
You will notice a red squiggly line under 'mfe1/Module'. That is because the URL does not exist at the time of compilation. So to stop the Typescript compiler from complaining about it declare the module in the projects\shell\src\decl.d.ts file.

declare module 'mfe1/Module';

Now everything is configured so now it's time to try it out. Serve both the shell and mfe1 in separate terminals

ng serve shell -o
ng serve mfe1 -o

After a browser window with shell opened (http://localhost:4200), click on Flights. This should load the Micro Frontend into the shell.
Also, ensure that the Micro Frontend also runs in standalone mode at http://localhost:4201.

Congratulations! You've implemented your first Module Federation project with Angular!

Now time for some tips and tricks
You can dynamically load remotes directly in app.routes.ts rather than in the webpack.config.js
So first, comment the remote mfe1 property in projects\shell\webpack.config.js.

remotes: {
// Comment this line:
// "mfe1": "http://localhost:4201/remoteEntry.js",
},

Then in the app.routes.ts use the function loadRemoteModule instead of the dynamic import statement:

import { loadRemoteModule } from '@angular-architects/module-federation';
const routes: Routes = [
	[...]
	{
		path: 'flights',
		loadChildren: () =>
			loadRemoteModule({
				type: 'module',
				remoteEntry: 'http://localhost:4201/remoteEntry.js',
				exposedModule: './Module'
		}).then(m => m.FlightsModule)
	},
	[...]
]

Restart both, the shell and the micro frontend (mfe1).

The shell should still be able to load the microfrontend. However, now it's loaded dynamically.

Conclusion

Microfrontends are not for every application as it requires considerable time and effort not just to create and introduce it into your codebase but also to maintain it. It gets a bit more complicated when you want to have shared states and bidirectional data passing. In most small to medium size projects, the benefits do not outweigh the cost, but in most large-scale projects where you want to have independent teams managing parts of the project, it is highly recommended to implement Module Federation. This situation may change in the future as the Angular Module Federation team is working hard to make it much more accessible and easy to use.

Additional Resources

More examples for Module Federation
https://github.com/module-federation/module-federation-examples
More Advance Features
https://github.com/angular-architects/module-federation-plugin/blob/main/libs/mf/README.md#example-️

Projects Completed till now.

Discover how we can help your business grow.

"Third Rock Techkno's work integrates complex frameworks and features to offer everything researchers need. They are open-minded and worked smoothly with the academic subject matter."

- Dr Daniel T. Michaels, NINS