Angular CLI 6 is here! With it, the Angular team has made it much easier to create libraries.
In this article, we show step by step how to create a simple library using Angular CLI 6. Let’s dive right in..
Setup
Let’s get set up to create our library. If you already have Angular CLI 6 installed, skip ahead to the next section.
Install Node.js
To start, we need to install Node.js. You can download the latest LTS installer from Node.js at https://nodejs.org/dist/v8.11.2/node-v8.11.2.pkg. Once the installer is finished, run the following command in the terminal to double check everything worked:
$ node --version
Install Angular CLI
After Node.js is installed, we can install Angular CLI. In a terminal window, issue the following command:
$ npm install -g @angular/cli
Once the install is finished, we can issue the following command to make sure we have everything in place:
$ ng --version
Project
Now that we have the set up finished, we can go ahead and create our new Angular project by issuing the ng new
command:
$ ng new angular-library --prefix al
Now let’s move into our new project with:
$ cd angular-library
If you are new to version 6 of Angular CLI, then you will notice that the .angular-cli.json
file has been replaced with angular.json
. New to this version, this file defines your workspace for the project just created. Within you will find two projects are created with the new command. We have our angular-library
project and our angular-library-e2e
project.
For more information on the angular.json
file, visit the Angular Workspace documentation page.
Not only can we now generate multiple applications easily in a new Angular project, but we can also generate our library.
Generate The Library
For this demo, I will use REQ | RES, a hosted REST API that will allow us to quickly get everything up and running. To generate our library for REQ | RES in the project, we will use the ng generate
command.
$ ng generate library reqres --prefix rr
This command has done two things within our project. In the angular.json
file we now have reqres
project below the angular-libraries-e2e
. The second is that in our project we now have a projects
folder that contains all the files our library needs to get started.
Create The Models
The next thing we want to do is create a couple of models for our library. For this demo we will just focus on the REQ | RES get list users API. If we go to https://reqres.in/api/users?page=1, we see that the JSON returned will be:
json { "page": 1, "per_page": 3, "total": 12, "total_pages": 4, "data": [ { "id": 1, "first_name": "George", "last_name": "Bluth", "avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/calebogden/128.jpg" }, { "id": 2, "first_name": "Janet", "last_name": "Weaver", "avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/josephstein/128.jpg" }, { "id": 3, "first_name": "Emma", "last_name": "Wong", "avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/olegpogodaev/128.jpg" } ] }
Let’s create the projects/reqres/src/lib/model
folder and our two new classes users
and user
. Enter the following into the termianl:
$ ng generate class model/user --project=reqres $ ng generate class model/users --project=reqres
Our user
model will be:
export class User { constructor( public id: number, public first_name: string, public last_name: string, public avatar: string ) {} }
Our users
model will be:
import { User } from './user'; export class Users { constructor( public page: number, public per_page: number, public total: number, public total_pages: number, public data: User[] ) {} }
Now let’s make our new models available for use. In the projects/reqres/src/public_api.ts
file, add the following:
export * from './lib/model/user'; export * from './lib/model/users';
Our entire public_api
file should now look as follows:
export * from './lib/reqres.service'; export * from './lib/reqres.component'; export * from './lib/reqres.module'; export * from './lib/model/user'; export * from './lib/model/users';
Create The Service
Angular CLI has already generated the projects/reqres/src/lib/reqres.service.ts
file for us so all we need to do is add in our code for calling the API. Let’s open the reqres.service.ts
and edit it so the final result is below:
import { Injectable } from '@angular/core'; import { HttpClient, HttpParams } from '@angular/common/http'; import { Observable } from 'rxjs'; import { Users } from './model/users'; @Injectable({ providedIn: 'root' }) export class ReqresService { private readonly apiRoot = 'https://reqres.in/api'; constructor(private httpClient: HttpClient) { } getUsers(page: number): Observable<Users> { const params = new HttpParams().set('page', String(page)); return this.httpClient.get<Users>(`${this.apiRoot}/users`, {params: params}); } }
This service is pretty straightforward, just a simple ‘get’ to the API. One thing to note is the property providedIn: 'root'
. This is new to Angular 6 and it specifies what module the service is to be set up for, in this case, root
. This allows for tree shaking to happen for services now.
Create the Components
Now let’s generate the users component for our library. To do this, let’s go back to our terminal and use the CLI to generate our files.
$ ng generate component users --project=reqres
All we will be doing in this component is generating a list of the users. The final component code will be the following:
import { Component, OnInit, Input } from '@angular/core'; import { ReqresService } from '../../public_api'; import { Users } from '../model/users'; @Component({ selector: 'rr-user', templateUrl: './users.component.html', styleUrls: ['./users.component.css'] }) export class UsersComponent implements OnInit { users: Users; @Input() pageNumber: number; constructor(private reqresService: ReqresService) { } ngOnInit() { this.getUsers(); } getUsers(): void { this.reqresService.getUsers(this.pageNumber).subscribe(arg => this.users = arg); } }
The HTML for the component is just the following simple list:
<div> <ul> <li *ngFor="let user of users.data"> {{user.last_name}}, {{user.first_name}} </li> </ul> </div>
Now that we have the component created, let’s make sure our module has everything that it needs.
In the reqres.module.ts
file we need to import the CommonModule
and the HttpClientModule
. The CLI added our declarations for the ReqresComponent
and the UsersComponent
.
Now we need to add the UsersComponent
to the exports
so it can be used outside of the module and our library is ready. The final module should look like this:
import { NgModule } from '@angular/core'; import { ReqresComponent } from './reqres.component'; import { CommonModule } from '@angular/common'; import { HttpClientModule } from '@angular/common/http'; import { UsersComponent } from './users/users.component'; @NgModule({ imports: [CommonModule, HttpClientModule], declarations: [ReqresComponent, UsersComponent], exports: [UsersComponent] }) export class ReqresModule { }
Build The Library
Now that we have everything ready for use, we need to build our library. This is as easy as the following command:
$ ng build reqres
With the build complete, we can go ahead and use it in our root application.
Use The Library
To use the library we first need to import it. In src/app/app.module.ts
add the ReqresModule
to the imports. The import of the module should look like:
import { ReqresModule } from 'reqres';
The final app.module.ts
will be:
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { ReqresModule } from 'reqres'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, ReqresModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
Notice that we are not importing the module using a relative path. We can set this up just like the library was in our node_modules because when the CLI created the library. It also added the following to the tsconfig.json
:
"paths": { "reqres": [ "dist/reqres" ] }
Once the module is published and brought into our application through node_modules, all we will need to do is go back into the tsconfig.json
and remove the path.
The last step will be to use our list in our component. Add “ to app.component.html
.
Now that we have everything in place lets serve the app by running:
$ ng serve
Once the server is up and running, going to http://localhost:4200 will display a list of three users in our application that was generated using our library.
Publish The Library
The only thing left to do is to publish our library. If we are publishing to NPM
this is issuing a few commands from the terminal. Just remember that to publish to NPM you do need an account. If you don’t have one, just go here to get set up https://www.npmjs.com/signup.
$ ng build reqres --prod $ cd dist/reqres $ npm publish
Final Thoughts
And that’s all you need to get your own libraries out for the world!
I hope that this tutorial helped you to have a good idea of how easy it is with Angular CLI 6 to set up your own libraries and to publish them for use. I look forward to seeing what new and exciting modules get created. Please let me know if you have any questions!