👨‍💻️ Concepts explained in this article are demonstrated using working code snippets and example GitHub project with live demo!

What are we going to learn?

Taxonomy of the Angular libraries based on their purpose

Different ways of implementing library (Angular CLI workspace vs monorepo)

Standard lazy loading of the application modules

How to NOT lazy load modules from Angular libraries

How to DO proper lazy loading of modules from Angular libraries

How will this change (for better) with Angular IVY

Taxonomy of the Angular libraries

Angular libraries can come in different shapes and for different purposes!

utils — a collection of various utilities, usually in form of stateless services

— a collection of various utilities, usually in form of stateless services component library — a collection of reusable simple (dumb) components with only plain API facilitated using mostly @Input and @Output decorators

— a collection of reusable simple (dumb) components with only plain API facilitated using mostly and decorators drop in component — a more complex component with its own state handling / data fetching which can still communicate with the parent application using @Input and @Output (eg pass in configuration or let the parent know about the outcome of some operation…)

— a more complex component with its own state handling / data fetching which can still communicate with the parent application using and (eg pass in configuration or let the parent know about the outcome of some operation…) sub-application — the most complex library which could also run as a stand alone application if the need be. Such a library can come with multiple modules with their own routes, components and services…

— the most complex library which could also run as a stand alone application if the need be. Such a library can come with multiple modules with their own routes, components and services… other? — let me know in the responses so I can add your use case to this list!

Of course it’s not always so clean cut and lines between the types can get blurry…

Our focus in this guide will be on the most complex “sub-application” like libraries!

Challenges that can be solved using sub-application libraries

shared complex functionality across many apps (eg search page, settings page)

splitting up features of the large application (with many lazy routes) into multiple libraries to further enhance isolation, speed up build / testing process, provide independent life-cycle and make it possible to run them as standalone apps

lego (add-on) style modules, application where people can enable / buy additional features

Ways to implement Angular libraries in 2019 (Angular CLI vs nrwl/nx)

Angular CLI got much better over time and currently provides very solid developer experience out of the box! Libraries developed in Angular CLI by default get their own package.json file so they are supposed to be published independently to npm repository as a standalone artifacts that are then consumed using npm install .

On the other hand, nrwl/nx gives us a monorepo style workspace with only single package.json file. Libraries are still imported with familiar from ‘@my-org/some-lib’; but this is now facilitated by the Typescript compiler aliases with relative paths to the local library directories instead of standard node node_modules/ resolution. Also, when published to npm, all the apps and libraries will be using the same version which is a monorepo approach to managing life-cycle!

It doesn’t really mater which style of development we choose. In the end, we still have to find a way to reference our library to be able to lazy load it and that’s what we are going to learn next!

How to lazy load libraries

Let’s start with something standard. We usually define lazy loaded routes as a relative path to some module in the local application codebase…

How we usually lazy load modules which are part of the application itself…

What would it mean if we wanted to adjust this to lazy load a module from a library?

The library can either come from node_modules/ as a standalone lib installed from npm or it can be a local library project in the Angular CLI (or nx) workspace.

Can we just reference lib with the string in these two cases?

Trying to reference library installed from npm or library which was built into the dist folder of local workspace doesn’t work!

These approaches don’t work!

How can we lazy load our library module using the expected syntax as shown in the first example above? In other words how can we provide our library module in a way so that we can reference it with a relative path like ./some-path/some.module#SomeModule ?

Luckily, there is a way where we can create extremely minimal wrapper modules locally inside of the consumer application codebase which will import the module from the library in a standard way using import { SomeLibModule } from '@my-org/some-lib' and then import that module inside of the @NgModule decorators imports: [SomeLibModule] array as show below.