Angular Monorepo Tutorial - Part 2: Project Graph

Run the command: npx nx graph. A browser should open up with the following contents:

Initial Project Graph

This is still different than the design from the start of Part 1:

Our Workspace Requirements

The Project Graph is derived from the source code of your workspace. Make the following adjustments to your existing projects, so that our Project Graph will match the design:

common-ui

Run the @nx/angular:component generator with the command:

~/myorg

npx nx g @nx/angular:component banner --project=common-ui --export

1 2> NX Generating @nx/angular:component 3 4CREATE libs/common-ui/src/lib/banner/banner.component.css 5CREATE libs/common-ui/src/lib/banner/banner.component.html 6CREATE libs/common-ui/src/lib/banner/banner.component.spec.ts 7CREATE libs/common-ui/src/lib/banner/banner.component.ts 8UPDATE libs/common-ui/src/lib/common-ui.module.ts 9UPDATE libs/common-ui/src/index.ts 10
Nx 15 and lower use @nrwl/ instead of @nx/

Then create a simple Banner component in the generated file:

libs/common-ui/src/lib/banner/banner.component.ts
1import { Component, Input } from '@angular/core'; 2 3@Component({ 4 selector: 'myorg-banner', 5 template: `<header>{{ title }}</header>`, 6 styleUrls: ['./banner.component.css'], 7}) 8export class BannerComponent { 9 @Input() title = ''; 10} 11

admin

Add the Banner component to the admin app:

apps/admin/src/app/app.component.ts
1import { Component } from '@angular/core'; 2 3@Component({ 4 selector: 'myorg-root', 5 template: ` 6 <myorg-banner title="Welcome to our admin app."> </myorg-banner> 7 `, 8}) 9export class AppComponent {} 10
apps/admin/src/app/app.module.ts
1import { NgModule } from '@angular/core'; 2import { BrowserModule } from '@angular/platform-browser'; 3import { CommonUiModule } from '@myorg/common-ui'; 4 5import { AppComponent } from './app.component'; 6import { NxWelcomeComponent } from './nx-welcome.component'; 7 8@NgModule({ 9 declarations: [AppComponent, NxWelcomeComponent], 10 imports: [BrowserModule, CommonUiModule], 11 providers: [], 12 bootstrap: [AppComponent], 13}) 14export class AppModule {} 15

products

Export a Product TS interface and some example products:

libs/products/src/lib/products.ts
1export interface Product { 2 id: string; 3 name: string; 4 price: number; 5} 6 7export const exampleProducts: Product[] = [ 8 { 9 id: '1', 10 name: 'Product 1', 11 price: 100, 12 }, 13 { 14 id: '2', 15 name: 'Product 2', 16 price: 200, 17 }, 18]; 19

store

Use both the Banner component from your common-ui lib, and the exampleProducts from your products lib:

apps/store/src/app/app.component.ts
1import { exampleProducts } from '@myorg/products'; 2import { Component } from '@angular/core'; 3 4@Component({ 5 selector: 'myorg-root', 6 template: ` 7 <myorg-banner title="Welcome to the store!"> </myorg-banner> 8 <ul> 9 <li *ngFor="let product of products"> 10 <strong>{{ product.name }}</strong> Price: {{ product.price }} 11 </li> 12 </ul> 13 `, 14}) 15export class AppComponent { 16 products = exampleProducts; 17} 18
apps/store/src/app/app.module.ts
1import { NgModule } from '@angular/core'; 2import { BrowserModule } from '@angular/platform-browser'; 3import { CommonUiModule } from '@myorg/common-ui'; 4 5import { AppComponent } from './app.component'; 6import { NxWelcomeComponent } from './nx-welcome.component'; 7 8@NgModule({ 9 declarations: [AppComponent, NxWelcomeComponent], 10 imports: [BrowserModule, CommonUiModule], 11 providers: [], 12 bootstrap: [AppComponent], 13}) 14export class AppModule {} 15

Now run npx nx graph again:

Matching Graph

Our Workspace Requirements

Your graph now matches the original design.

The Project Graph is more than just a visualization - Nx provides tooling to optimize your task-running and even automate your CI based on this graph. This will be covered in more detail in: 4: Workspace Optimization.

What's Next