The Angular Library Series - Creating a Library with Angular CLI

Angular libraries just got a lot easier to create thanks to the combination of Angular CLI and ng-packagr.

Todd Palmer
May 28, 2018 · 11 min read
Image for post
Image for post
Metso Library in Tampere, Finland
Image for post
Image for post

The Angular Library Series

This is the first article in my Angular Library Series. For your convenience here are links to all the articles in the series:

  1. The Angular Library Series — Building and Packaging
  2. The Angular Library Series — Publishing

Introduction

When we use ng new, Angular CLI creates a new workspace for us.

  • An application project
    This will be a test harness for our library. Sometimes this application is used as documentation and example usage of the library.

Goals

  • Use Angular CLI to create a workspace with the same name as our intended Angular library: example-ng6-lib
  • We will have a test application for our example-ng6-lib library named:
    example-ng6-lib-app
  • In our example-ng6-lib workspace generate an Angular library named:
    example-ng6-lib
  • Our Angular library will have the prefix of enl to remind us of Example Ng6 Library.
  • We will test our example-ng6-lib by importing it as a library into our example-ng6-lib-app application.

Angular 6

At the time of this writing Angular 6 is still quite new. So, there are a couple of the changes that will affect this tutorial.

Creating an Angular Workspace

Our first goal was to create an Angular workspace named example-ng6-lib.

For Angular 7

Angular 7 added the very useful flag --createApplication. If you are using Angular 7, you should follow the approach I describe in my article:
Angular Workspace: No Application for You!
and not the approach below for Angular 6 where we rename the Workspace.

For Angular 6

Because of how the projects work in Angular 6, we need to create the Angular Workspace in a bit of a round-about way. We need to create a workspace named example-ng6-lib-app and then rename it to example-ng6-lib:

ng new example-ng6-lib-app
rename example-ng6-lib-app example-ng6-lib
cd example-ng6-lib
ng serve
Image for post
Image for post

Angular 6 Configuration: angular.json

Before we move on to creating our library let’s take a quick look at the new Angular configuration file: angular.json.

"projects": {
"example-ng6-lib-app": {
...
},
"example-ng6-lib-app-e2e": {
...
}
},
  • example-ng6-lib-app-e2e: This is the default project for end to end testing. During this article, you can safely ignore this project.

Generating a Library Module

Now we can generate a new library called example-ng6-lib in our workspace.

ng generate library example-ng6-lib --prefix=enl
$ ng generate library example-ng6-lib --prefix=enlCREATE projects/example-ng6-lib/karma.conf.js (968 bytes)
CREATE projects/example-ng6-lib/ng-package.json (191 bytes)
CREATE projects/example-ng6-lib/ng-package.prod.json (164 bytes)
CREATE projects/example-ng6-lib/package.json (175 bytes)
CREATE projects/example-ng6-lib/src/test.ts (700 bytes)
CREATE projects/example-ng6-lib/src/public_api.ts (191 bytes)
CREATE projects/example-ng6-lib/tsconfig.lib.json (769 bytes)
CREATE projects/example-ng6-lib/tsconfig.spec.json (246 bytes)
CREATE projects/example-ng6-lib/tslint.json (317 bytes)
CREATE projects/example-ng6-lib/src/lib/example-ng6-lib.module.ts (261 bytes)
CREATE projects/example-ng6-lib/src/lib/example-ng6-lib.component.spec.ts (679 bytes)
CREATE projects/example-ng6-lib/src/lib/example-ng6-lib.component.ts (281 bytes)
CREATE projects/example-ng6-lib/src/lib/example-ng6-lib.service.spec.ts (418 bytes)
CREATE projects/example-ng6-lib/src/lib/example-ng6-lib.service.ts (142 bytes)
UPDATE angular.json (4818 bytes)
UPDATE package.json (1724 bytes)
UPDATE tsconfig.json (471 bytes)
  • Adds dependencies for ng-packagr to our package.json
  • Adds a reference to the example-ng6-lib build path in tsconfig.json
  • Creates sources for our library in projects/example-ng6-lib

example-ng6-lib project in angular.json

Take a look at angular.json. Especially notice that in the projects object we have a new project: example-ng6-lib.

ng-packagr dependency in package.json

When generating our library Angular CLI realizes that it needs ng-packagr. So, it adds it to our devDependencies in our workspace package.json:

"ng-packagr": "^3.0.0-rc.2",

build path in tsconfig.json

When testing example-ng6-lib we want to be able to import it like a library and not just another set of files that are part of our application. Typically, when we use a 3rd party library we use npm install and the library gets deployed to our node-modules folder.

"paths": {
"example-ng6-lib": [
"dist/example-ng6-lib"
]
}

example-ng6-lib sources

The src folder for our library is contained in projects/example-ng6-lib. In our library Angular CLI created a new module with a service and a component. Also, looking there we see a few more files:

Building the Library

Before we can use our newly generated library we need to build it:

ng build example-ng6-lib

Using the Library in Our Application

One of the central ideas of building a library is that we typically have an application we build along with our library in order to test it.

Importing the example-ng6-lib Module

Let’s modify our AppModule in: src\app\app.module.ts

import { ExampleNg6LibModule } from 'example-ng6-lib';

Displaying the example-ng6-lib Component

To keep things simple let’s just add the default generated component from our library to our AppComponent template in: src\app\app.component.html

<enl-example-ng6-lib></enl-example-ng6-lib>

Running Our Application

As always we can run our application using:

ng serve
Image for post
Image for post

Expanding Our Library

Now we know how to build our library and run our application using a component from the library. Let’s expand our library and see what we need to do to add another component.

  1. Add the component to our library module’s exports.
  2. Add the component to our entry file.
  3. Rebuild our library after we make changes to it.
  4. Use the new component in our application

Generating a library component

When generating a component for our library we use the --project flag to tell Angular CLI that we want it to generate the component in our library project. Let’s generate a simple component in our library and call it foo:

ng generate component foo --project=example-ng6-lib
CREATE projects/example-ng6-lib/src/lib/foo/foo.component.html (22 bytes)
CREATE projects/example-ng6-lib/src/lib/foo/foo.component.spec.ts (607 bytes)
CREATE projects/example-ng6-lib/src/lib/foo/foo.component.ts (257 bytes)
CREATE projects/example-ng6-lib/src/lib/foo/foo.component.css (0 bytes)
UPDATE projects/example-ng6-lib/src/lib/example-ng6-lib.module.ts (347 bytes)

Exporting the component from our library’s module

We need to add the Foo Component to the exports of our library module. If we don’t, we will get a template parse error telling us "enl-foo" is not a known element when we try to include the component in our application.

Adding the component to the entry file

As we noted before our library project has an entry file that defines its public API:
projects\example-ng6-lib\src\public_api.ts

export * from './lib/foo/foo.component';

Rebuilding our library

After making the changes, we need to rebuild our library with:

ng build example-ng6-lib
ng build example-ng6-lib --watch

Using our new library component

Finally, add the element <enl-foo></enl-foo> as the last line of your app.component.html file. It should look something like this:

Image for post
Image for post

Looking Ahead

In Part 2 of this series we discuss building, packaging, and actually using our generated library in another application.

Image for post
Image for post

Angular In Depth

The place where advanced Angular concepts are explained

Todd Palmer

Written by

Computer Scientist, Fujitsu Distinguished Engineer, and Senior Software Engineer http://t-palmer.github.io

Angular In Depth

The place where advanced Angular concepts are explained

Todd Palmer

Written by

Computer Scientist, Fujitsu Distinguished Engineer, and Senior Software Engineer http://t-palmer.github.io

Angular In Depth

The place where advanced Angular concepts are explained

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store