Nx Angular Code Generators

Straight from the documentation, "Similar to the Angular CLI, Nx comes with code generation abilities. What the Angular CLI calls 'Schematics,' Nx calls 'Generators.'"

Shortly: Angular Schematics = Nx Generators

So, basically, Nx generators help you create code and scaffolding like components, libraries, etc.

The command npx nx list @nx/angular offers a list of Nx Generators capabilities. The full list includes more generators and some executors/builders related to webpack and module federation.

Partial list of Nx generators capabilities

Partial list of Nx Generators capabilities

You can also find similar features by installing the Nx Console extension for your code editor. the Nx console supports VSCode, and IntelliJ, and ships an LSP for Vim.

Nx Console extension

Nx Console extension

It doesn’t matter if you are working specifically on an Nx angular standalone application or a monorepo, I highly recommend you install it. It will simplify your job and it will come useful later in the section “Step 1 — Create Component In Library”.

Generating Angular Components

You can generate an Angular component with

npx nx g @nx/angular:component hello-world

or using the Nx Console Extension:

Generate Angular component with Nx Console Extension

Generate Angular component with Nx Console Extension

This is exactly like Angular CLI where you would use ng g c hello-world to create a HelloWorldComponent inside the app directory.

The only difference is that the selector will start with nxapp- instead of app-. Other than that, you can import the component in the template as usual.

// app.component.html

<nxapp-hello-world></nxapp-hello-world>

Testing Components

If you import HelloWorldComponent in AppComponent remember to update AppComponent unit test to make it aware of the new component used in its template.

Update app.component.spec.ts as follows:

// app.component.spec.ts

...
import { HelloWorldComponent } from './hello-world/hello-world.component';

describe('AppComponent', () => {
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [RouterTestingModule],
      declarations: [AppComponent, NxWelcomeComponent, HelloWorldComponent],
    }).compileComponents();
  });
  ...

  it('should render title', () => { }
  it(`should have as title 'nxapp'`, () => {}
}

Then you can run:

npx nx test

to run all unit tests. Or, if you prefer running a single unit test:

$ npx nx test nxapp --test-file=src/app/app.component.spec.ts

where you have to specify the project name and the name of the test file you want to run.

This is a simple case but to keep the app structured we should follow Nx practices when creating new components and features.

As a rule of thumb, a well-architected Nx app has a library folder, also called libs or features or modules, where features reside. Even though we are working specifically on an Nx angular standalone application, the same principles hold for Nx React or monorepo.

Generating Angular Libraries

You can generate an Nx Angular library using the following syntax

npx nx g @nx/angular:library library-name

It is important to understand that in the Nx world, a library is something like a feature or a module. In this post, I will use the term library and lib interchangeably, however, you might see a module or feature folder in other codebases.

For the sake of structure, we will create a libs folder that contains all libraries (features/modules) we need.

Thinking of a company that engages with both business and private customers, we may want to structure libraries accordingly.

First, we create two libraries for business relationships (clients and suppliers), then we’ll create one more library for private customers (clients).

npx nx g @nx/angular:library clients --directory=libs/business
npx nx g @nx/angular:library suppliers --directory=libs/business
npx nx g @nx/angular:library clients --directory=libs/private

Nx will automatically place the libraries inside the libs folder. Since this is an Nx Angular Standalone Application, the src folder at the root level is the Angular standalone application.

All libraries can be used by the Angular app, therefore, we place the libs folder as a peer of src. We get to the following architecture:

e2e/
libs/
  business/
    clients/
    suppliers/
  private/
    clients/
src/
project.json            
tsconfig.spec.json
tsconfig.app.json
tsconfig.json
nx.json                        
package.json
...

In so doing we get to independent local libraries that can be tested and built independently.

This principle applies to Nx angular standalone applications as well as Nx React or monorepo.

Testing Libraries

For instance, you can run

npx nx test nxapp --test-file=libs/business/clients

to test only the Clients library.

As usual, if you re-run the command without changing anything Nx will use the cached results to give you a faster response.

Keeping Libraries Independent

As mentioned above, keeping libraries independent from each other is a good practice. When some code should be used in multiple libraries, you should create a shared library folder containing the shared code.

npx nx g @nx/angular:library shared

The code above generated a shared library folder inside the libs folder.

The current architecture becomes:

e2e/
libs/
  business/
    clients/
    suppliers/
  private/
    clients/
  shared/
src/
project.json            
tsconfig.spec.json
tsconfig.app.json
tsconfig.json
nx.json                        
package.json
...

Now, since we created independent libraries and we are not using them in AppComponent, they can be visualized as distinct nodes in the workspace.

Nx Graph

Nx comes with a good visualization tool out of the shelf: graph.

Nx creates a graph of all the dependencies between projects in your workspace using two sources of information:

  • package.json

  • Typescript import statements

By running

npx nx graph

we get to the following view:

Nx dependency graph

Nx dependency graph

So far, the only dependency is the e2e test suite which depends on the app.

While the e2e test suite depends on the app (nxapp), the app doesn’t depend on the tests.

Moreover, as reported by Victor Savkin (Nx co-founder), The building of the app and the running of the e2e tests don’t have to happen at the same or on the same machine. One machine can build the application and another one can run the tests.

0
Subscribe to my newsletter

Read articles from Lorenzo Zarantonello directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Lorenzo Zarantonello
Lorenzo Zarantonello