In this article, we’ll see how we can use Nx (Nrwl Extensions) to create a full-stack application. The application will feature a frontend application built with Angular and a backend application that uses Nest.js.
Nrwl Extensions (Nx) is a project started by Google developers. It is an open-source project that provides a set of extensions (schematics and builders) to extend the functionality of the Angular . It provides commands for creating workspaces that contain multiple projects. Nrwl Extensions not only provides commands for managing complex and robust Angular projects but also for creating full-stack projects using Express and Nest.js
Before we get started, this article requires a basic understanding of Angular and Nest.js.
Nrwl doesn’t replace the Angular CLI) — rather it extends the functionality of the CLI with commands to create multiple apps within a workspace. To get started working with Nrwl, you’ll have to install the Angular CLI first. Run the following command to install the CLI:
npm install -g @angular/cli
To use Nrwl, you have the options of installing it globally by running the following command:
npm install -g @nrwl/schematics
Or you could leverage the power of npx to create a workspace using the create-nx-workspace
:
npx create-nx-workspace my-workspace
If you wish to integrate Nx into an existing Angular application, run the following command in a terminal within your project folder:
ng add @nrwl/schematics
To begin creating our project, we’ll create a workspace using the create-nx-workspace
command. Run the following command to create a workspace called fullstack-angular
.
create-nx-workspace fullstack-angular
This command will generate a workspace with no bootstrapped applications within. A workspace provides setup for listing using tslint
, editor support for linting using tsconfig.json
and prettier
for code formatting.
It also provides a jest
config file for quick testing. Jest is a testing framework by Facebook.
Next, we’ll see how we can create and serve a frontend application that runs on Angular using the CLI and Nx.
Nx is a smart tool that supports a mono-repo development style. It provides a way to allow the projects within the workspace to interact with each other. With Nx you can manage different project types within the workspace, ranging from libraries to applications.
Nx provides a visualization tool that lets you see how the projects within your workspace are connected. You can access this tool by running the following command:
npm dep-graph
The screenshot above shows how the projects in the workspace are connected. Next we’ll create the frontend application using the CLI.
Run the following command on a terminal within the project folder:
ng generate application my-store
After running this command, you’ll see different prompts. Let’s walk through each one:
? In which directory should the application be generated?
The first command asks where you’d like your application to be generated. It’s best to leave this blank so your application will be generated within the apps
folder in the workspace.
? Would you like to add Angular routing? (y/N)
The next prompt is about routing. If you wish to create routes in your application, reply with y
or you can skip this prompt.
PS: You can always add routing later on in your application.
? Which stylesheet format would you like to use? (Use arrowkeys)
❯ CSS
The next prompt is asking about your stylesheet of choice. If you prefer working with pre-processors, you can choose whichever you’re most comfortable with.
? Which Unit Test Runner would you like to use for the application? (Use arrow keys)
Here you have to choose the unit test runner you want to use with your application. Jest
has been configured for the workspace already, so I’d recommend it. But you can still choose Karma
if you’re more comfortable with it. It’s great to have options and Nx
does well providing these options.
? Which E2E Test Runner would you like to use for the application? (Use arrow keys)
Then you have the e2e
prompt. You can use either of them, whichever suits your application.
Finally, there’s the tags prompt, which you can leave blank. This prompt is asking for tags you wish to add that will be used for linting in your application:
? Which tags would you like to add to the application? (used for linting)
Again, you can leave this blank.
After the prompts, the command generates an Angular application within the apps
folder, it also generates an e2e
folder for running end-to-end testing for the application. You can start the application by running the command below:
ng serve my-store
This should start your application on http://localhost:4200.
Nx provides a command to integrate state management into our application using @ngrx/store. Running the command below will generate actions
, effects
, and actionTypes
for populating your store and a reducer
for acting on the dispatched actions. To read more on using @ngrx/store
, you can visit their official website and read through their robust documentation.
Run the following command to add state management to the my-store
application:
ng generate ngrx todos --module=apps/my-store/src/app/app.module.ts
The command above tells the CLI to generate an ngrx
store named todos
in the my-store
app module. If you check your apps/my-store/app
folder, you should see a newly generated folder named +state
. It contains files for actions
, effects
, selectors
, and reducer
. It also contains spec files to test them.
The backend application will be making use of Nest.js. According to the documentation:
Nest is a framework for building efficient, scalable Node.jsserver-side applications. It uses progressive JavaScript, is built with TypeScript (preserves compatibility with pure JavaScript), and combines elements of OOP Object Oriented Programming, FP (Functional Programming, and FRP (Functional Reactive Programming).
Nx offers two frameworks for creating backend applications: Express
and Next.js
. We’ll be going with Nest.js
because of how similar it is to Angular and how it integrates seamlessly with Angular applications. It breeds familiarity because Nest.js uses similar techniques for development. They use modules, providers, and pipes just like Angular, and controllers in place of components.
With Nx, you can create a backend application that communicates seamlessly with the frontend application using the following command:
ng generate node-app store-api --frontend-project=my-store
The command above creates a Node application called store-api
and creates a proxy to the my-store
Angular application. This makes it easy for the Angular application to communicate with the server.
By running this command, you’ll be faced with some prompts asking about your framework of choice, the unit testing framework, etc. The framework for this project is Nest.js, so ensure you select that option.
After the command has been run successfully, start the server by running the command below:
ng serve store-api
Then you can visit http://localhost:3333/api. Your view should be similar to the screenshot below:
Let’s see how we can make requests to the backend application. Nx made this easier by creating a proxy to the backend. Within the my-store
app, there’s a file proxy.conf.json
, and within the file there’s the setup for proxying requests:
{
"/api": {
"target": "http://localhost:3333",
"secure": false
}
}
Which means, if we want to communicate with the backend, we’ll make requests to /api
endpoint and it’ll proxy to [http://localhost:3333](http://localhost:3333)
.
Next, let’s update the Angular application to fetch items from the backend(store-api
). Open the apps/my-store/src/app/app.component.ts
file and update it to make a request to the server using the HttpClient:
// apps/my-store/src/app/app.component.ts
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http'
import { Observable } from 'rxjs';
interface Product{
name: String;
price: Number;
stock: Number
}
@Component({
selector: 'fullstack-angular-root',
templateUrl: './app.component.html',
styleUrls: \['./app.component.css'\]
})
export class AppComponent {
products: Observable<Product\[\]>;
constructor(private http: HttpClient){
this.products = this.http.get<Product\[\]>('/api/products');
}
}
Then we’ll update the view template to render the list of products. Open the apps/my-store/src/app/app.component.html
file and copy the snippet below into the file:
<section>
<ul>
<li \*ngFor="let product of products | async">
Name: <span>{{product.name}}</span> <br/>
Price: <span>{{product.price}}</span><br/>
Stock: <span>{{product.stock}}</span>
<hr>
</li>
</ul>
</section>
Next, we’ll import the HttpClientModule
into the project’s app.module.ts
file. Open the file and include the HttpClientModule
in the imports
array.
// apps/my-store/src/app/app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
// ... others imports
import { HttpClientModule } from '@angular/common/http';
@NgModule({
declarations: \[AppComponent\],
imports: \[
// ...other imports,
HttpClientModule,
\],
providers: \[\],
bootstrap: \[AppComponent\]
})
export class AppModule {}
In the Angular application, we’re making a request to the api/products
endpoint. This route hasn’t been created in the node application. Let’s update the app controller to create a products
route that returns a list of products.
Open the apps/store-api/src/app/app.controller.ts
file and update it to be similar to the code below:
// apps/store-api/src/app/app.controller.ts
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get('products')
getData() {
return this.appService.getData();
}
}
Then update the service file (app.service.ts
) to return the list of products:
import { Injectable } from '@nestjs/common';
interface Product{
name: String;
price: Number;
stock: Number
}
@Injectable()
export class AppService {
private products: Product\[\] = \[
{
name: 'First product',
price: 22.45,
stock: 10
},
{
name: 'Second product',
price: 12.45,
stock: 5
}
\]
getData(): Product\[\] {
return this.products;
}
}
Start the node backend by running the following command (ng serve store-api
) and the frontend using ng serve my-store
.
Navigate to http://localhost:4200 and you should see something similar to the screenshot below:
We’ve successfully set up a full-stack application with the help of Nrwl extensions. Nx is also useful for creating libraries — you can set up these libraries to communicate with your backend and frontend applications. You can also set up a library that can be easily published to npm. To learn more about creating libraries using Nx, visit their official documentation here.
In this article, we’ve seen how we can use Nx to create a full-stack application. The application will feature a frontend application built with Angular and a backend application that uses Nest.js. Nx provides extensions to the Angular CLI that help us manage workspaces that can feature multiple applications and libraries. These workspaces feature setup that supports linting using tslint
and prettier
for code formatting. Visit the project’s official documentation to read more about the project.
#angular #node-js #web-development