Publishing AoT compliant Angular 2 Packages
Ahead of Time compilation in Angular 2 seems fancy and Minko Gechev says it the best way on this post: Ahead-of-Time Compilation in Angular 2.
There might be excellent explanations and examples on how to setup an AoT compiled web app (e.g. angular-cli), but there hardly seems to be content on how to make your new shiny or existing flashy package AoT compliant.
tl;dr: If a published package doesn’t contain .metadata.json files, they are incompatible for AoT compilation.
Let’s dive in on how to make your package AoT compliant.
Dependencies
Angular 2 compiler and its command line interface (cli) can simply be pulled in via npm.
$ npm install typescript @angular/compiler @angular/compiler-cli --save-dev
Setup a build config file
It is better to setup a separate config for building the package. The Angular core team names it tsconfig-build.json so let’s stick to that. It should resemble the following:
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": false,
/**
creates type definitions for the compiled files d.ts
**/
"declaration": true,
/**
output directory for the compiled files
**/
"outDir": "./lib",
"stripInternal": true
},
/**
array of files to be compiled, in our case is our entry file
**/
"files": [
"index.ts"
],
/**
compiler options for ngc (angular compiler)
**/
"angularCompilerOptions": {
/**
don't produce .ngfactory.ts or .css.shim.ts files,
they get published where the package will be consumed
**/
"skipTemplateCodegen": true
}
}Create build script through npm
This is pretty straight forward as shown below:
“scripts”: {
…
“build”: “ngc -p ./tsconfig-build.json”
…
}Running this script will generate files in the specified directory. This seems straight forward but there is a catch, we aren’t using the standard typescript compiler i.e. tsc to compile our package instead we are using Angular2’s compiler-cli, so what difference does that make? Compiling with ngc creates another set of files with a .metadata.json extension to host the file specific metadata defined in the decorators.
These .metadata.json files are the ones which make a package AoT compliant. Simply publish your package and pull them without fear as they will support AoT compilation wherever you consume them.
Now, there is another twist in the tale. If your package contains components which rely on external templates and styles, this method will fail. Currently ngc is unable to include referenced templates and styles in its build process. Since that is a separate issue on its own, I will address that in a separate post. Until then, happy publishing :)