What Is It Anyway?
One of the many benefits and unique features of Angular is its modularity. These modules, known as `NgModules
`, are essentially containers for code dedicated to a specific domain or closely related set of features. Modules may include components, service providers or any other code defined by the containing NgModule. Because of Angular’s use of `NgModules
`, it makes code reuse very clean and easy. This is where Angular Libraries come to the rescue.
Angular Libraries were created to provide a simple way to organize, build and export reusable parts of code (or modules) with other applications. Whether you intend to build libraries to be shared and reused in a monorepo or you intend to publish them to a third-party package manager, such as npm, Angular Libraries are the perfect solution.
Getting Started
Now, let’s get started by building our very own angular library. You will need to have the Angular CLI installed locally to do so. If you’re not sure if you already have the CLI installed, simply open your terminal and type:
ng --version
If you already have the CLI installed your terminal should look something like this:
If not, no need to sweat as you can simply run the following command:
npm i @angular/cli -g
We are now ready to roll! For this example, we will build a UI Components library so that we can share common components used within an organization. This will enable a consistent user interface throughout our applications and teams that will be easier to consume and maintain over time.
Creating A New Project
An important thing to note before we get started is that Angular libraries cannot exist on their own. They must exist inside of an Angular application. Therefore, we need to first create a new application that will both generate our ui-components library as well as consume our library to verify it’s working as expected. We can do that through the CLI by running the following command:
ng new my-org-packages
This creates a new Angular application named my-org-paackages. After the installation completes, run the following command to serve the application:
ng serve
Generating A Libary
Now that we have a working Angular application, generate the ui-components library. We will use the CLI to generate this as well:
ng g library ui-components
This created a /projects folder in the root of our application with the name of the library specified in the previous command (In our example /ui-components). Technically, we now have a working library that could be consumed and/or published to npm. Our library, as is, doesn’t have any meaningful parts to share, however, so let’s do that next.
Building The Library
For the sake of brevity, let’s create a few default components using the Angular CLI:
ng g c loader --project=ui-components ng g c card --project=ui-components ng g c modal --project=ui-components
This created 3 components and declared them inside the root of our UiComponents.module.ts
file.
@NgModule({ declarations: [LoaderComponent, CardComponent, ModalComponent] }) export class UiComponentsModule {}
We could also generate a module to wrap similar components in our library as well. Let's create a MenuModule that will include several menu-specific components.
ng g m menu --project=ui-components
Your UiComponentsModule
should now look like this:
@NgModule({ imports: [MenuModule], declarations: [LoaderComponent, CardComponent, ModalComponent] })
Now let’s generate some components for the MenuModule
:
ng g c menu/menu --project=ui-components ng g c menu/menu-item --project=ui-components ng g c menu/logo --project=ui-components
Now we have 3 components that are all declared in the MenuModule
.
@NgModule({ declarations: [MenuComponent, MenuItemComponent, LogoComponent], }) export class MenuModule {}
Exporting The Libarary
Just like an NgModule
inside an Angular application, we can only consume the parts of a module that are exported. So let’s add all our components to the exports array of our modules.
@NgModule({ imports: [MenuModule], declarations: [LoaderComponent, CardComponent, ModalComponent], exports: [MenuModule, LoaderComponent, CardComponent, ModalComponent] }) export class UiComponentsModule {}
@NgModule({ declarations: [MenuComponent, MenuItemComponent, LogoComponent], exports: [MenuComponent, MenuItemComponent, LogoComponent], }) export class MenuModule { }
Now that our modules export the parts we want to consume, we have to also include all the library parts we want to be exposed as part of the library. These get declared in the public-api.ts
file in the library’s /src
folder.
export { UiComponentsModule } from './ui-components.module'; export { LoaderComponent } from './loader/loader.component'; export { CardComponent } from './card/card.component'; export { ModalComponent } from './modal/modal.compoennt'; export { MenuModule } from './menu/menu.module'; export { MenuComponent } from './menu/menu.component'; export { MenuItemComponent } from './menu/menu-item.component'; export { LogoComponent } from './menu/logo.component';
*Note: If you use barrel rolls for the various modules and parts of your library it makes the public-api.ts
much cleaner than explicitly listing all the items like the example above.
Publishing To Npm
There are multiple ways to not only consume our libraries- but to also distribute them. Now let’s publish this package to npm (one of the most common use cases).
There are 2 main approaches to publishing libraries; manually publishing, or by publishing them through a CI process. Using a CI to publish your libraries is going to be the better long-term solution but is beyond the scope of this article. Fortunately, publishing libraries manually to npm is very simple.
First, you need to create an npm account. Now that you have an account, login to your account using:
npm login
This will request your user credentials and password. After following the prompts and successfully logged into your npm account via terminal, publishing is as simple as the following 4 steps.
- Make sure your libraries
package.json
version is set to the version you’ve chosen. - Build your library by running
ng build ui-components
. - Change your directory to the newly built code from the previous step using
cd dist/ui-components
. - Finally, run
npm publish
to publish the library to your npm account.
Consuming The Package
Now that the library has been published to npm, we can now consume it inside of other projects. Inside of the application you want to consume your new library, go ahead and run the following command with the appropriate npm package name:
npm install ui-components
*Note: You may also preface your package name with your npm username as a namespace. Example: @briebug/ui-components
.
Now that the package has been installed as a dependency inside your application we can begin referencing it inside of that application.
@NgModule({ declarations: [...], imports: [UiComponentsModule,...] exports: [...], }) export class AppModule { }
Now you can begin referencing those reusable components anywhere inside of your app.
<ui-components-loader></ui-components-loader> <ui-components-menu> <ui-components-menu-item [link]="..." [title]="..."></ui-components-menu-item> </ui-components-menu> <ui-components-card> <div> ... </div> </ui-components-card>
Closing
In this article, we covered the why and the how for generating Angular libraries. Though we used a shared ui-components library as our example, there is an infinite number of use cases for libraries. I think you’ll find that once you start creating libraries, you won’t be able to stop; libraries can exponentially increase productivity, scalability, and reusability in your projects.