Building Node Applications with Nx

NodeJS is a JavaScript runtime which can be run on servers. It can be used to build tools and backend applications. Often, it is used in conjunction with frontend applications but developed separately. Nx now has the ability to build NodeJS applications in the same repo as frontend ones!

Developing Node Applications

Creating a Node Application

To create a node application, use the following command:

ng generate node-app my-node-app

This generates the following application which is setup for development and testing:

apps/
  my-node-app/
    src/
      main.ts
    jest.config.js
    tsconfig.app.json
    tsconfig.spec.json
    tslint.json

Options

Below are some of the important options you can change when creating a NodeJS application:

  • Directory
    • By default, the node application will be a top level directory under apps but you can use a directory to group a NodeJS application alongside it’s frontend counterpart.
  • Tags
    • You can assign tags to the NodeJS application to help restrict the types of libraries it can use. This can be particularly useful to ensure frontend dependencies are not brought into a backend application where they would be incompatible.
  • Framework
    • If you are migrating an existing NodeJS application into Nx or would like to use a different framework, you may pass none for this option. An express application is generated by default.

To see a full list of options, run the following command:

ng generate node-app --help

Building a Node Application

Nx makes it simple to develop Node Applications using the Angular CLI, the same tool used to build frontend applications. Bundling a node application is exactly like bundling a frontend application and can be done with the following command:

ng build my-node-app

Serving a Node Application

Serving a Node application is also just like serving frontend applications and can be done with the following command:

ng serve my-node-app

This starts the node application and restarts it when changes are made to the source code. This makes it easy to start developing and iterating quickly without a lot of setup.

Testing a Node Application

Jest is used for testing a node application because it does not require running the code in a browser as Karma does it. Testing a Node application is done with the following command:

ng test my-node-app

Note: e2e testing of a node-application should be done through the testing of the frontend applications which depend on it.

Benefits of developing frontend and backend applications together

Developing backend applications is often done separately from the frontend. This creates a disconnect between the backend code from the frontend code and makes it hard to keep them in sync. Below are some reasons why building Angular applications in combination with their API services is beneficial.

Synchronizing Development and Deployments

Many times, it is hard to synchronize development between different repos which make it difficult to introduce breaking changes in dependencies. With one repo, the backend and frontend applications can be deployed in sync with one another to ensure compatibility between the two versions. While creating breaking changes in the backend will still mean updating all the users of the application, the change can safely be released once all of the breaking changes are accounted for. This mitigates the need for versioning or other techniques to ease the pain of breaking changes.

Increased Awareness cross platform

It is sometimes difficult for backend and frontend teams to fully understand the other side of the stack. With all code co-located in the same repo, there is more visibility with into how backends function and how they are used. Frontend developers can understand what happens under the hood of the endpoints they use and backend developers can see where the endpoints are being used on the frontend.

Sharing Code

Data models, business logic, and other code can be shared between frontend and backend by creating libraries. Use the following command to generate a library which can be used on backend applications:

ng generate lib my-data-type --no-module

Then create a my-data.ts file within the library and add it to the public api as follows:

export interface MyData {
  Id: string;
  firstName: string;
  lastName: string;
}
export * from ‘./lib/my-data’;

Which can be exported in both frontend and backend applications as follows:

import { MyData } from@myOrg/my-data-type’;

By writing interfaces in a library and using them in both frontend and backend applications, all parts of the stack are guaranteed to have the same representation of the data. You can expand on the above idea and develop contracts which are agreed upon by users of the backend application. By having an accurate representation of data provided by the backend, frontend applications can use the typings to catch possible breaking changes increasing developer productivity and preventing bugs from being introduced. Make sure to check out our article announcing the feature for a specific example!

Understanding implications of changing code across platforms

Nx offers dependency visualization generated from source code to allow for an always up to date map of dependencies. Running the following command will generate the dependency graph below:

yarn dep-graph
# or for npm
npm run dep-graph

image

The above chart shows that the data-type is used by both the frontend and the backend. It is also evident that the frontend depends on the backend.

Intelligently Building and Testing Applications

Because Nx is able to determine the dependencies of applications and libraries, it is able to intelligently decide which projects need to be rebuilt and retested when changes are made to the repository. For example, if the backend is touched only the following projects highlighted in red need to be tested with the following command:

yarn affected:test --base master

image

Looking for more best practices for enterprise-scale Angular development from the Nrwl team?

Visit Nx Playbook