Nx Angular Lazy-loading Libraries

Lazy-loading Libraries In An Nx Angular Standalone App

So far, our Nx angular standalone application has three independent libraries and a shared module (library) that could contain shared code for the libraries.

In the following example, I’ll show how to lazy-load one library. For the sake of simplicity, I will add a single standalone component in the client library (libs/business/clients) and we will see how to import it in three steps:

  1. Create a Component In the Library

  2. Export Component

  3. Lazy-load Library In App

After these three steps, we will see what the new dependency graph looks like.

Step 1 — Create a Component In the Library

You can do this step manually or using the Nx code generators, which I recommend.

Here, I want to give a big shout-out to the Nx team because if you installed the Nx Console extension you can use it as follows to create the right component in the right place with all necessary imports, automatically.

Open the Nx console (on the sidebar of your IDE) and select nx generate @nx/angular:component.

Tip: You can also right-click on the lib folder (libs/business/clients/src/lib) and select Nx generate. Once you select nx generate @nx/angular:component Nx will prefill the project name.

nx generate @nx/angular:component

nx generate @nx/angular:component

Select the name of the component you want to create. In our case, it is clients.

Then, select the project where the component should be created. In our workspace, projects correspond to libraries, so we will select business-clients.

Use Nx code generators to generate a component in a library

Use Nx code generators to generate a component in a library

While this screen is open, Nx runs a dry-run of the code generation, in the terminal. You can also see the command you should use to get the same result.

Dry run of nx generate @nx/angular:component

Dry run of nx generate @nx/angular:component

If you tick the export and standalone boxes, Nx will run another dry-run of the code generation given the new preferences.

As you can see below, ticking those boxes update index.ts and create an Angular standalone component. As a reminder, Nx angular standalone application and Angular standalone components are not the same thing.

Nx angular standalone application refers to the Nx workspace structure when there is a single Angular application. Angular standalone components refer to Angular.

After Nx generates ClientsComponent in libs/business/clients/src/lib/clients, the folder structure looks like the following:

e2e/
libs/
  business/
    clients/
      src/
        lib/
          clients/
            clients.component.css
            clients.component.html
            clients.component.spec.ts
            clients.component.ts
          business-clients.module.ts
          index.ts
          test-setup.ts
        ...
    suppliers/
  private/
    clients/
  shared/
src/
project.json

Make sure ClientsComponent is an Angular standalone component and it imports CommonModule in the imports array, as shown below.

// clients.component.ts

import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';

@Component({
  selector: 'nxapp-clients',
  standalone: true,
  imports: [CommonModule],
  templateUrl: './clients.component.html',
  styleUrls: ['./clients.component.css'],
})
export class ClientsComponent {}

Step 2 — Export Component

Update the file index.ts in libs/business/clients/src/lib/ to export the newly created ClientsComponent.

export * from './lib/business-clients.module';

export * from './lib/clients/clients.component';

If you used Nx code generators in step 1, this file should be already up to date.

Step 3 — Lazy-load Library In App

Finally, we can import ClientsComponent into our app. One way to do that is to lazy-load ClientsComponent when users navigate to a specific route.

To do that, I updated the routes array of nxapp as follows:

// app.routes.ts

import { Route } from '@angular/router';
import { NxWelcomeComponent } from './nx-welcome.component';

export const appRoutes: Route[] = [
  {
    path: '',
    component: NxWelcomeComponent,
    pathMatch: 'full',
  },
  {
    path: 'clients',
    loadComponent: () =>
      import('@nxapp/business/clients').then((m) => m.ClientsComponent),
  },
];

When users navigate to /clients, the app will load ClientsComponent.

At this point, the new dependency graph looks like the following. Note how the dotted line indicates that the lazy-loaded library might be a dependency if it is loaded.

Nx dependency graph

Nx dependency graph

You can repeat the steps above for each library you want to lazy-load in your app.

Import Libraries In NgModule

A second way to use a library inside your app is by importing it in NgModule.

We can use the Nx code generators to create a new standalone component called SuppliersComponent in libs/business/suppliers/src/lib/suppliers.

Or you can run:

npx nx generate @nx/angular:component --name=suppliers --project=business-suppliers --export=true --standalone=true

Now we need to import SuppliersComponent in nxapp.

In AppModule,

  • add import { SuppliersComponent } from ‘@nxapp/business/suppliers’;

  • add SuppliersComponent to the imports array of NgModule

// app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
import { appRoutes } from './app.routes';
import { NxWelcomeComponent } from './nx-welcome.component';
import { HelloWorldComponent } from './hello-world/hello-world.component';
import { SuppliersComponent } from '@nxapp/business/suppliers';

@NgModule({
  declarations: [AppComponent, NxWelcomeComponent, HelloWorldComponent],
  imports: [
    BrowserModule,
    RouterModule.forRoot(appRoutes, { initialNavigation: 'enabledBlocking' }),
    SuppliersComponent,
  ],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}

Now you can use SuppliersComponent in nxapp by using its selector, nxapp-suppliers, in any templates. For instance:

// app.component.html

<nxapp-suppliers></nxapp-suppliers>
<router-outlet></router-outlet>

The new dependency graph becomes

Nx dependency graph

Nx dependency graph

Unlike the business-clients library, business-suppliers is a hard dependency because it is eagerly loaded in NgModule when the app starts.

Nx Angular Standalone Application — Conclusions

While creating this Nx Angular Standalone Application a few things became clear.

Nx can support you and your team by providing a clear architecture that makes your app more maintainable as it grows.

Think of Nx as a wrapper around your Angular or React app. The Angular app, all unit tests, and e2e tests are written as you already do. Nx doesn’t change any of that.

The Nx Console extension is really powerful. It simplifies and speeds up using Nx with Angular or React.