Angular Nx Tutorial - Step 8: Create Libs

Nx.dev Tutorial | Angular | Step 8: Create Libraries

Libraries are not just a way to share code in Nx. They are also useful for factoring out code into small units with a well-defined public API.

Public API

Every library has an index.ts file, which defines its public API. Other applications and libraries should only access what the index.ts exports. Everything else in the library is private.

UI Libraries

To illustrate how useful libraries can be, create a library of Angular components.

Run npx nx g @nrwl/angular:lib ui.

You should see the following:

myorg/
ā”œā”€ā”€ apps/
ā”‚   ā”œā”€ā”€ todos/
ā”‚   ā”œā”€ā”€ todos-e2e/
ā”‚   ā””ā”€ā”€ api/
ā”œā”€ā”€ libs/
ā”‚   ā”œā”€ā”€ data/
ā”‚   ā””ā”€ā”€ ui/
ā”‚       ā”œā”€ā”€ src/
ā”‚       ā”‚   ā”œā”€ā”€ lib/
ā”‚       ā”‚   ā”‚   ā”œā”€ā”€ ui.module.spec.ts
ā”‚       ā”‚   ā”‚   ā””ā”€ā”€ ui.module.ts
ā”‚       ā”‚   ā””ā”€ā”€ index.ts
ā”‚       ā”œā”€ā”€ jest.conf.js
ā”‚       ā”œā”€ā”€ tsconfig.app.json
ā”‚       ā”œā”€ā”€ tsconfig.json
ā”‚       ā”œā”€ā”€ tsconfig.spec.json
ā”‚       ā””ā”€ā”€ tslint.json
ā”œā”€ā”€ nx.json
ā”œā”€ā”€ package.json
ā”œā”€ā”€ tools/
ā”œā”€ā”€ tsconfig.base.json
ā””ā”€ā”€ tslint.json

The libs/ui/src/lib/ui.module.ts file looks like this:

1import { NgModule } from '@angular/core';
2import { CommonModule } from '@angular/common';
3
4@NgModule({
5  imports: [CommonModule],
6})
7export class UiModule {}

Add a Component

Add a component to the newly created ui library by running:

npx nx g component todos --project=ui --export
myorg/
ā”œā”€ā”€ apps/
ā”‚   ā”œā”€ā”€ todos/
ā”‚   ā”œā”€ā”€ todos-e2e/
ā”‚   ā””ā”€ā”€ api/
ā”œā”€ā”€ libs/
ā”‚   ā”œā”€ā”€ data/
ā”‚   ā””ā”€ā”€ ui/
ā”‚       ā”œā”€ā”€ src/
ā”‚       ā”‚   ā”œā”€ā”€ lib/
ā”‚       ā”‚   ā”‚   ā”œā”€ā”€ todos/
ā”‚       ā”‚   ā”‚   ā”‚   ā”œā”€ā”€ todos.component.css
ā”‚       ā”‚   ā”‚   ā”‚   ā”œā”€ā”€ todos.component.html
ā”‚       ā”‚   ā”‚   ā”‚   ā”œā”€ā”€ todos.component.spec.ts
ā”‚       ā”‚   ā”‚   ā”‚   ā””ā”€ā”€ todos.component.ts
ā”‚       ā”‚   ā”‚   ā”œā”€ā”€ ui.module.spec.ts
ā”‚       ā”‚   ā”‚   ā””ā”€ā”€ ui.module.ts
ā”‚       ā”‚   ā””ā”€ā”€ index.ts
ā”‚       ā”œā”€ā”€ jest.conf.js
ā”‚       ā”œā”€ā”€ tsconfig.app.json
ā”‚       ā”œā”€ā”€ tsconfig.json
ā”‚       ā”œā”€ā”€ tsconfig.spec.json
ā”‚       ā””ā”€ā”€ tslint.json
ā”œā”€ā”€ nx.json
ā”œā”€ā”€ package.json
ā”œā”€ā”€ tools/
ā”œā”€ā”€ tsconfig.base.json
ā””ā”€ā”€ tslint.json

Add a todos input to libs/ui/src/lib/todos/todos.component.ts.

1import { Component, OnInit, Input } from '@angular/core';
2import { Todo } from '@myorg/data';
3
4@Component({
5  selector: 'myorg-todos',
6  templateUrl: './todos.component.html',
7  styleUrls: ['./todos.component.css'],
8})
9export class TodosComponent implements OnInit {
10  @Input() todos: Todo[];
11
12  constructor() {}
13
14  ngOnInit() {}
15}

And update todos.component.html to display the given todos:

1<ul>
2  <li *ngFor="let t of todos" class="todo">{{ t.title }}</li>
3</ul>

Use the UI Library

Now import UiModule into apps/todos/src/app/app.module.ts.

1import { BrowserModule } from '@angular/platform-browser';
2import { NgModule } from '@angular/core';
3
4import { AppComponent } from './app.component';
5import { HttpClientModule } from '@angular/common/http';
6import { UiModule } from '@myorg/ui';
7
8@NgModule({
9  declarations: [AppComponent],
10  imports: [BrowserModule, HttpClientModule, UiModule],
11  providers: [],
12  bootstrap: [AppComponent],
13})
14export class AppModule {}

And update app.component.html:

1<h1>Todos</h1>
2
3<myorg-todos [todos]="todos"></myorg-todos>
4
5<button (click)="addTodo()">Add Todo</button>

Restart both npx nx serve api and npx nx serve todos and you should see the application running.