Accueil / Blog / Métier / 2017 / How to create an Angular library

How to create an Angular library

Par Eric Brehault publié 08/02/2017, édité le 10/03/2017
Having a light and clean distribution AND running tests on Travis, showing demo on Github Pages, etc.
How to create an Angular library

Creating an Angular project is super easy thanks to the Angular CLI, but at the moment creating a library is not that obvious.

As far as I know there is no official guideline from Angular, but we can find a lot of useful resources to create an Angular lib:

When I started my last Angular library (Angular Traversal, an alternative to the router), I had several requirements:

  • produce a light distribution (without a bunch of dependencies people might not want in their project), supporting AoT,
  • be able to run a demo locally so I can play with my lib, and also publish this demo on Github pages,
  • be able to run tests locally (once again, without a bunch of dependencies) and on Travis.

And none of the different resources I have mentionned was covering all of them.

Disclaimer: I am sure there are smarter and cleaner approaches than mine, and I am sure the situation will improve rapidly so this entire article will turn out to be obsolete, but still, it does the job at the moment and I am quite happy with it.

The core principle: divide et empera

My first idea was to restrict my tooling to the minimum. To build a library, using ngc should be just fine. But if I want to launch tests or run a demo, it will require more tools and more dependencies in my package. Moreover configuring myself karma or webpack is not fun, I would definitely prefer to use the ng CLI. But then my package would be carrying a lot of dependencies... Simplicity or comfort, how to choose?

After many attempts, I haven't been able to find the right balance between those two expectations. So I decided to split those different concerns into two different packages:

  • the root package, that will only contain my library code, and will only use ngc;
  • a secondary package located in the ./tests folder, that will be a full ng CLI project containing demos and tests.

The root package

The root package is the one that gets published at the end. It is very simple.

Regarding package.json:

  • All the Angular core dependencies are listed as peer dependencies.
  • The "main" and "types" entries target the /dist folder
And the AOT build is done with ngc, so that's basically the only tool we need here.

The ./tests package

Using the ng CLI, we create a new project in the ./tests folder.

Of course, we want this project to use our library. But we cannot use npm link! It produces side-effects which makes our library module unusable when we run our tests (at least with Angular CLI 1.0.0-beta.22, but I guess it will be fixed in a later version).

So we just copy the ./dist folder from the root package to our tests package. It can be done with a simple npm script command in the root package.json:

"test": "npm run build && rm -rf ./tests/lib && cp -r ./dist ./tests/lib && cd tests && ng test --single-run",

This tests package will obviously be used to write and run tests, but it can also be used to create a small demo.

Travis setup

Our .travis.yml file will just have to launch the previously mentionned npm script.

We just have to make sure we install the peerDependencies properly, which can be done that way:

npm info . peerDependencies | sed -n 's/^{\{0,1\}[[:space:]]*'\''\{0,1\}\([^:'\'']*\)'\''\{0,1\}:[[:space:]]'\''\([^'\'']*\).*$/\1@\2/p' | xargs npm i

(By the way, wouldn't be nice if npm provided an option to do that automatically?)

And we also need to install the tests package (not just the root one):

cd ./tests && npm install && cd ..

And that's it.

Github pages

We also want to publish our demo (built in the tests package) on Github pages. Let's say we want it in a folder named "/demo" in our root folder (in the gh-pages branch).

We do that using the angular-cli.json outDir entry:

"outDir": "../demo",

And by setting a proper base href when building the demo:

ng build --base-href \"/demo/\"

(it can be done as a command script in the tests package.json).

And we get our demo running!

Voir aussi
React 16.3 : Introduction de la context API React 16.3 : Introduction de la context API 06/04/2018

React 16.3 apporte son lot de nouveautés, mais surtout la version stable de la context API.

Découverte de React Native Découverte de React Native 18/04/2016

Présentation de React Native, quelles sont ses possibilités et peut-on l'utiliser en prod ?

Bien démarrer avec JavaScript Bien démarrer avec JavaScript 15/12/2015

Callbacks, this, scope... mais qu'est-ce que c'est que ce langage ?

Mise en pratique de RxJS dans Angular Mise en pratique de RxJS dans Angular 24/07/2017

Les quelques bases suffisantes pour bien utiliser RxJS dans Angular 2, 4 ou 5.

Comment mettre en place Angular Universal Comment mettre en place Angular Universal 29/06/2017

Toutes les étapes détaillées et expliquées. Les pièges à éviter.