Dynamically loading micro frontends – Micro Frontend with Angular Elements

Let’s prepare our main application gym diary to consume the micro frontend that we prepared previously. To do this, let’s start by creating a new module in the application. On the command line, we will use the following Angular CLI commands:
ng g m exercise –routing
ng g c exercise/exercise

With the preceding commands, we create the module with the generated route file and a component that will be responsible for loading mfe.

Let’s adjust the exercise-routing.module.ts file to target the component:
import { NgModule } from ‘@angular/core’;
import { RouterModule, Routes } from ‘@angular/router’;
import { ExerciseComponent } from ‘./exercise/exercise.component’;
const routes: Routes = [
  {
    path: ”,
    component: ExerciseComponent,
    title: ‘Exercise Registry’,
  },
];
@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule],
})
export class ExerciseRoutingModule {}

In the routes array, we define a base route for the exercise registration component as it will be loaded via lazy loading.

Next, we will refactor the home-routing.module.ts file as follows:
const routes: Routes = [
  {
    path: ”,
    component: HomeComponent,
    children: [
      {
        path: ‘diary’,
        loadChildren: () =>
          import(‘../diary/diary.module’).then((file) => file.DiaryModule),
      },
      {
        path: ‘exercise’,
        loadChildren: () =>
          import(‘../exercise/exercise.module’).then(
            (file) => file.ExerciseModule
          ),
      },
      {
        path: ”,
        redirectTo: ‘diary’,
        pathMatch: ‘full’,
      },
    ],
  },
];

Our HomePage module contains the menu, and in this section, we are adding the new module to be loaded in the correct area of the interface.

To finish adding this new module, let’s change the home.component.html file:
  <li>
    <a
      routerLink=”./exercise”
      class=”flex items-center space-x-2 text-white”
    >
      <span>Exercise Registry</span>
    </a>
  </li>

With the new menu item added to the home template, we now have the task of including the micro frontend generated in the other project in our interface.

For this, we have a community package called @angular-extensions that allows us to load our micro frontend simply using a directive, as we will see later. But first, let’s install this dependency in our project using the following command:
npm i @angular-extensions/elements

Once installed, we can change the ExerciseModule module:
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from ‘@angular/core’;
import { CommonModule } from ‘@angular/common’;
import { ExerciseRoutingModule } from ‘./exercise-routing.module’;
import { ExerciseComponent } from ‘./exercise/exercise.component’;
import { LazyElementsModule } from ‘@angular-extensions/elements’;
@NgModule({
  declarations: [ExerciseComponent],
  imports: [CommonModule, LazyElementsModule, ExerciseRoutingModule],
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class ExerciseModule {}

In this file, we are first adding the library module called LazyElementsModule to have access to the directive that we will use in the component. Furthermore, we have a new property in the metadata called schemas. In it, we are informing Angular with the CUSTOM_ELEMENTS_SCHEMA token that this module will receive elements from outside the project. By default, Angular checks whether the tag used in the template exists in the project or in the HTML standard, such as the input tag.

As we are going to import the exercise-form tag defined by our micro frontend here, this attribute will prevent Angular from carrying out this check at the project compile time.

In the exercise.component.ts file, we will add a new attribute:
import { Component } from ‘@angular/core’;
@Component({
  selector: ‘app-exercise’,
  templateUrl: ‘./exercise.component.html’,
  styleUrls: [‘./exercise.component.css’],
})
export class ExerciseComponent {
  elementUrl = ‘http://localhost:8080/main.js’;
}

Here, we are defining the address where the micro frontend’s main files will be served.

Finally, let’s change the component template:
<exercise-form *axLazyElement=”elementUrl”> </exercise-form >

Here, we are declaring the new exercise-form element, and to load it, we use the axLazyElement directive assigning the micro frontend address.

To run our project, make sure the micro frontend is being served with the npm run serve-mfe command. With everything configured, we can see the result of our work:

Figure 11.3 – Exercise form dynamically loaded into the main application

Summary

In this chapter, we explored the architecture of micro frontends and how to apply one to an Angular project.

We learned about the concept of the architecture, its advantages, and its trade-offs. We explored how the main reason for opting for this architecture is its flexibility in relation to the organizational structure of each team, as several teams can work on different parts of the frontend project independently.

We also learned how we can ideally divide our application into micro frontends.

With all these concepts, we applied our project by creating a small application using Angular’s standalone components feature and preparing it to be loaded by another project using the Angular elements library.

Finally, we performed dynamic loading in our main application with the help of the @angular-extensions/elements library.

In the next chapter, we will explore the best practices for deploying an Angular application.

No Responses

Leave a Reply

Your email address will not be published. Required fields are marked *



Terms of Use | About yeagerback | Privacy Policy | Cookies | Accessibility Help | Contact yeagerback