In the last time, I helped numerous companies implementing Angular SPAs for microservice environments. As outlined in a former blog article, there are several approaches for this.

In this article, I show how to implement one of them in 6 steps: A shell loading micro frontends on demand. Other than in my article about micro frontends and web components, I don’t use web components for the macro architecture. Instead, I just go with ordinary SPAs which are loaded and bootstrapped on demand. For the micro architecture I still use web components.

While this decision simplifies the implementation, we can still isolate different applications using shadow DOM as Angular also supports this standard associated with web components for traditional Angular components since its first day.

The case study loads a simple client-a and a simple client-b into the shell. Also, the former one shares a widget with the latter one:

The source code for this can be found in my GitHub account here.

Step 0: Make sure you need it

Make sure this approach fits to your architectural goals. Micro frontends come with a lot of consequences. You should be aware of them. My blog article here provides some guidance.

Step 1: Implement Your SPAs

Implement your micro frontends as ordinary Angular applications. In an micro service architecture it’s quite common that every part gets its own repository in order to decouple them as much as possible (see Componentization via Services) On contrary, I’ve seen a lot of micro frontends based upon monorepos for practical reasons.

Of course, now, we could discuss when the term micro frontend is appropriate. I won’t, because this discussion doesn’t really help. What counts is to find a architecture that fits your goals and to be aware of its consequences.

If we go with a monorepo, we have to ensure, e. g. with linting rules, that the micro frontends are not coupled to each other. Nrwl’s Nx provides a great solution for that: It allows to set up access restrictions defining which library can access which other one. Also, Nx can detect which parts of your monorepo are affected by a change in order to only recompile and retest them.

Of course, this decision has consequences, as discussed in the mentioned blog article.

To make routing across micro frontends easier, it’s a good idea to prefix all the routes with the application’s name. In the following case, the application name is client-a

@NgModule({
  imports: [
    ReactiveFormsModule,
    BrowserModule,
    RouterModule.forRoot([
      { path: 'client-a/page1', component: Page1Component },
      { path: 'client-a/page2', component: Page2Component },
      { path: '**', component: EmptyComponent}
    ], { useHash: true })
  ],
  [...] 
})
export class AppModule {
  [...]
}

#unkategorisiert #angular

6 Steps to your Angular-based Microfrontend Shell
13.15 GEEK