DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Related

  • 10 Mistakes You Should Avoid When Integrating Augmented Reality in FinTech Software Development
  • Deployment of Spring MVC App on a Local Tomcat Server
  • Micro Frontends Architecture
  • Blueprint for Seamless Software Deployment: Insights by a Tech Expert

Trending

  • The Future of Java and AI: Coding in 2025
  • Monolith: The Good, The Bad and The Ugly
  • How To Introduce a New API Quickly Using Quarkus and ChatGPT
  • Build a Simple REST API Using Python Flask and SQLite (With Tests)
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Deployment
  4. Implementing Micro Frontends in Angular: Step-By-Step Guide

Implementing Micro Frontends in Angular: Step-By-Step Guide

This guide explains how to implement micro frontends in Angular applications with scalability and maintainability in mind.

By 
Tapesh Mehta user avatar
Tapesh Mehta
·
Jul. 11, 24 · Tutorial
Likes (3)
Comment
Save
Tweet
Share
19.0K Views

Join the DZone community and get the full member experience.

Join For Free

Micro frontends are architectural styles in which independently deliverable frontend applications form a unified whole. This method enables teams to work independently on different parts of an application for scalability and easier maintenance. This guide will demonstrate how to implement micro frontends in Angular applications, the benefits and challenges, and the steps with code samples.

Benefits of Micro Frontends

  1. Scalability: Teams can develop, test, and deploy features independently, scaling the development process.
  2. Autonomous teams: Different teams can work on separate micro frontends, using their preferred tools and frameworks.
  3. Maintainability: Smaller codebases are easier to maintain, understand, and refactor.
  4. Incremental upgrades: Micro frontends can be updated incrementally without affecting the entire application.

Challenges of Micro Frontends

  1. Complexity: Increased complexity in managing multiple repositories and coordinating deployments.
  2. Performance: Potential performance overhead due to multiple independent bundles.
  3. Shared state management: Managing shared state across micro frontends can be challenging.
  4. Consistency: Ensuring a consistent look and feel across different micro frontends requires careful planning.

When more than one team works on various areas of an application, differences in design and user experience usually creep in. To mitigate this, a solid design system and common component library should be established across all teams. This includes defining a set of UI components, styles, and guidelines that are uniform across the application. It also requires regular communication and collaboration between teams to align on design decisions and consistency.

Setting up Micro Frontends With Angular

Step 1: Creating the Shell Application

The shell application serves as the container for the micro frontends. It handles routing and provides a common layout.

1. Create a New Angular Application

PowerShell
 
ng new shell-app
cd shell-app


2. Set up Angular Router

In app-routing.module.ts, define routes for the micro frontends.

TypeScript
 
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

const routes: Routes = [
  { path: 'micro-frontend1', loadChildren: () => import('micro-frontend1/Module').then(m => m.MicroFrontend1Module) },
  { path: 'micro-frontend2', loadChildren: () => import('micro-frontend2/Module').then(m => m.MicroFrontend2Module) },
  { path: '', redirectTo: '/micro-frontend1', pathMatch: 'full' }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }


Step 2: Creating Micro Frontend Applications

Each micro frontend is a separate Angular application that can be developed and deployed independently.

1. Create New Angular Applications

PowerShell
 
ng new micro-frontend1
ng new micro-frontend2


2. Configure Webpack Module Federation Plugin

To enable dynamic loading of micro frontends, we use the Webpack Module Federation Plugin. Add the following configuration to webpack.config.js in each micro frontend project.

JavaScript
 
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");

module.exports = {
  output: {
    publicPath: "http://localhost:4201/",
    uniqueName: "micro-frontend1"
  },
  plugins: [
    new ModuleFederationPlugin({
      name: "micro-frontend1",
      filename: "remoteEntry.js",
      exposes: {
        './Module': './src/app/app.module.ts',
      },
      shared: {
        "@angular/core": { singleton: true, strictVersion: true },
        "@angular/common": { singleton: true, strictVersion: true },
        "@angular/router": { singleton: true, strictVersion: true },
      }
    })
  ],
};


Repeat similar steps for micro-frontend2 with appropriate adjustments.

3. Adjust angular.json for Custom Webpack Configuration

Modify angular.json to use the custom Webpack configuration.

JSON
 
"architect": {
  "build": {
    "builder": "@angular-devkit/build-angular:browser",
    "options": {
      "customWebpackConfig": {
        "path": "./webpack.config.js"
      }
    }
  }
}


4. Expose Components and Modules

Expose the necessary components and modules in each micro frontend. For example, in micro-frontend1:

TypeScript
 
// src/app/app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }


Step 3: Integrating Micro Frontends Into the Shell Application

1. Configure Webpack Module Federation in Shell

Similar to the micro frontends, configure the Webpack Module Federation Plugin in the shell application.

JavaScript
 
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");

module.exports = {
  output: {
    publicPath: "http://localhost:4200/",
    uniqueName: "shell-app"
  },
  plugins: [
    new ModuleFederationPlugin({
      remotes: {
        "micro-frontend1": "micro-frontend1@http://localhost:4201/remoteEntry.js",
        "micro-frontend2": "micro-frontend2@http://localhost:4202/remoteEntry.js"
      },
      shared: {
        "@angular/core": { singleton: true, strictVersion: true },
        "@angular/common": { singleton: true, strictVersion: true },
        "@angular/router": { singleton: true, strictVersion: true },
      }
    })
  ],
};


2. Configure Routes in the Shell Application

Ensure the routes in the shell application are correctly configured to load the micro frontends.

TypeScript
 
// app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

const routes: Routes = [
  { path: 'micro-frontend1', loadChildren: () => import('micro-frontend1/Module').then(m => m.MicroFrontend1Module) },
  { path: 'micro-frontend2', loadChildren: () => import('micro-frontend2/Module').then(m => m.MicroFrontend2Module) },
  { path: '', redirectTo: '/micro-frontend1', pathMatch: 'full' }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }


3. Run the Applications

Ensure all applications (shell and micro frontends) are running.

PowerShell
 
ng serve --project shell-app
ng serve --project micro-frontend1
ng serve --project micro-frontend2


Visit http://localhost:4200 to see the shell application, which should load the micro frontends as configured. 

Step 4: Handling Shared State and Communication

Managing shared state and communication between micro frontends is crucial for a cohesive user experience.

1. Using a Shared Library

Create a shared library that can be used by all micro frontends to manage the state and provide common services.

PowerShell
 
ng generate library shared


In the shared library, define common services and state management logic. For instance: 

TypeScript
 
// shared/src/lib/state.service.ts
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class StateService {
  private stateSubject = new BehaviorSubject<any>({});
  state$ = this.stateSubject.asObservable();

  setState(newState: any) {
    this.stateSubject.next(newState);
  }
}


2. Using the Shared Library in Micro Frontends

Import and use the shared library in each micro frontend to maintain a consistent state and facilitate communication.

TypeScript
 
// micro-frontend1/src/app/app.component.ts
import { Component } from '@angular/core';
import { StateService } from 'shared';

@Component({
  selector: 'app-root',
  template: `<h1>Micro Frontend 1</h1>`
})
export class AppComponent {
  constructor(private stateService: StateService) {
    this.stateService.setState({ key: 'value' });
  }
}


Repeat similar steps for other micro frontends to ensure they can communicate via the shared state service. 

Conclusion 

Implementing micro frontends with Angular requires configuring a shell application to host multiple independent micro frontends, and configuring Webpack Module Federation for dynamic loading and shared state and communication. This architecture fosters scalability, maintainability, and autonomous team operations. However, it also brings complexity and performance considerations to be managed carefully.

Follow this guide to get started developing micro frontends in Angular that leverage the benefits and solve the challenges you face.

AngularJS application Software deployment

Opinions expressed by DZone contributors are their own.

Related

  • 10 Mistakes You Should Avoid When Integrating Augmented Reality in FinTech Software Development
  • Deployment of Spring MVC App on a Local Tomcat Server
  • Micro Frontends Architecture
  • Blueprint for Seamless Software Deployment: Insights by a Tech Expert

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!