HOW-TO: Angular library divided in independent feature sub libraries [closed]
Asked Answered
L

1

6

I am currently developing an Angular library (in Angular v 8.1.0) and wondering how is it possible to have it "split in different sub-libraries"?

For example, Angular (@angular) is split somehow in different "parts" like:

  • @angular/common
  • @angular/core
  • @angular/forms
  • etc.

and for instance, @angular/common has different sub-directories available to import from:

  • @angular/common/http
  • @angular/common/locale
  • @angular/common/testing

I am wondering how to do this kind of structuring in my own Angular library to keep different context elements independent one of each other. Let's say my library is called cool-lib and there are different feature modules which contain their own services/components/etc: common, featureA, featureB.

I would like to achieve something like this:

import { CommonService } from 'cool-lib/common';
import { FeatAComponent, FeatAService } from 'cool-lib/feature-a';
import { FeatBModule } from 'cool-lib/feature-b';

instead of having:

import { 
  CommonService, 
  FeatAComponent, 
  FeatAService,
  FeatBModule
} from 'cool-lib';

and it even also would be nice to be able to independently bump version numbers of the different feature modules or simply having installed only those that are going to be needed without having to install the whole libary (let's say I only need featureA).

For example, having on my package.json:

{
  "dependencies": {
    "cool-lib/common": "1.0.0",
    "cool-lib/feature-a": "1.0.0",
    "cool-lib/feature-b": "1.3.0"
  }
}

or just:

{
  "dependencies": {
    "cool-lib/feature-a": "1.0.0"
  }
}

instead of:

{
  "dependencies": {
    "cool-lib": "1.0.0"
  }
}

I have read a lot about creating Angular libraries so far, but couldn't find this specific use case as all of them cover just the very basics of creating and publishing them on npm... so any help on this is very welcomed!

Louie answered 28/8, 2019 at 12:35 Comment(0)
M
10

Angular already supports multiple sub-libraries out of the box.

The default project structure contains an "app" application that is a regular Angular project, and then you add additional sub-libraries that are Angular Library projects. There are placed in the library sub-folder.

A single Angular project can contain multiple sub-library projects.

Each sub-library project can be published as a separate npm package, because they have their own package.json file.

npm supports something called scoped package names. Which allows you to name a package as @angular/core where @angular is the scope of the package.

You can add a scoped library to your current Angular project like this.

ng generate library @my-scope/my-library

When you import from a scoped project it must be prefixed with the scope.

For example;

import { CommonService } from '@cool-lib/common';
import { FeatAComponent, FeatAService } from '@cool-lib/feature-a';
import { FeatBModule } from '@cool-lib/feature-b';

In the above, the name @cool-lib is the scope and common is the name of the npm package.

Using scopes lets you do two basic things (as far as I'm aware).

  1. prevents name collision with other packages, for example @cool-lib/animations will not collide with @angular/animations
  2. organizes packages into node_modules/@cool-lib
Meakem answered 28/8, 2019 at 12:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.