How package
Angular libaries

in 20 minutes

Attila Olah

Angular Package Format

Used by Angular Team to publish @angular/... packages

• Attempts to support all modern tooling

and others...

• Support for AOT

• Support for tree-shaking

The goal in general is to make the app easily usable for devs

Requirements for AOT

TypeDefinitions

• Metadata files

• Use Angular Compiler

• It produces compiled js files, metadata and d.ts files

How generate these?

• ngfactory and ngstyle files are not needed for libraries

Requirements for AOT

Example tsconfig.json

{
  "compilerOptions": {
    "declaration": true,
    "module": "es2015",
    "target": "es5",
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "skipLibCheck": true,
  },
  "angularCompilerOptions": {
    "strictMetadataEmit": true,
    "skipTemplateCodegen": true,
    "flatModuleOutFile": "my-module-id.js",
    "flatModuleId": "my-module-id"
  }
}

• Typescript reads compilerOptions

• ngc reads angularCompilerOptions

Optimizations for your libary

• Generate fewer modules (small modules has a cost)

• Angular Team suggests to use Rollup

• Flat modules structure

• Inline templates & styles

• Do not re-export everything in an NgModule

• This breaks tree-shaking :(

import { NgModule } from '@angular/core';
import { FirstModule } from './first.module';
import { SecondModule } from './second.module';

@NgModule({
 imports: [FirstModule, SecondModule],
 exports: [FirstModule, SecondModule]
})
export class YourLibary { }

Optimizations for your libary

• One NgModule per component

// fist.module.ts
import { NgModule } from '@angular/core';
import { FirstComponent } from './first.component';
export * from './first.component';

@NgModule({
 imports: [FirstComponent],
 exports: [FirstComponent]
})
export class FirstModule { }
// module.js entry point
import { NgModule } from '@angular/core';
import { FirstModule } from './first.module';
import { SecondModule } from './second.module';

@NgModule({
 imports: [FirstModule, SecondModule],
 exports: [FirstModule, SecondModule]
})
export class YourLibary { }

Recommendations

• Publish ES5 FESM and ES2015 FESM modules

• Ship UMD bundles for legacy reasons only

• Modern tools doesn't use it / need it

• It prevents the optimizations I have talked about

Useful links

Angular Package Format - Spec

Quickstart project - filipesilva/angular-quickstart-lib

Complex example - angular/material2

Thanks

Attila Olah

How package Angular Libaries

By Attila Oláh

How package Angular Libaries

  • 1,765