Getting your Angular 2 library ready for AoT

There are 2 basic things you need to get your Angular 2 library ready for consumers to use it in an AoT compiled application.

  1. Don’t use the runtime (JiT) compiler
  2. Make sure your NgModule is statically analyzable.
  3. Include *.metadata.json files in your npm package (See this issue comment.)
All referenced libraries must include the *.metadata.json file along side any *.d.ts files they produce…

#1 is pretty obvious when you’re doing it and kind of rare. (See this article if you think you really need the runtime compiler.)

#2 can be difficult and gives rather unhelpful error messages. So I’ve written a separate article to help people satisfy this requirement.

#3 is less obvious and I haven’t found good documentation or any examples of libraries actually doing this. If you don’t do #3, users of your YourAwesomeModule library that try the AoT compiler will get this error:

Error: Unexpected value ‘YourAwesomeModule’ imported by the module ‘AppModule’

So, I’m writing down the steps for library maintainers (and excited pull-requesters) to follow.

1. Make sure that you have the required packages installed as devDependencies:

npm install --save-dev @angular/compiler-cli typescript@2 @angular/platform-server @angular/compiler

2. Generate *.ngFactory.ts files in their own directory

Add to tsconfig.json:

"angularCompilerOptions": {
"genDir": "compiled"
}

3. Don’t include generated code in version control

Add to .gitignore:

/compiled
*.metadata.json
# These lines were probably already there
*.map.js
*.js # or /src/**/*.js

4. Don’t include *.ngFactory.ts files in the npm package

Consumers of the library will generate these on their own. Add to .npmignore:

/compiled
# or
*.ngFactory.ts
# or no change needed if you already have
*.ts

5. Use Angular 2’s wrapper around typescript

In your package.json scripts replace all references to tsc with ngc.

6. Run the compiler

Build your library the same way you always have, but now your package.json scripts will use ngc instead of tsc. Make sure that the *.metadata.json files are next to their associated *.d.ts files.

You’ll need to fix any errors in this step that are caused by #2 above. I’ve written a separate article that will help you deal with these (somewhat obtuse) errors.

Note: If you use webpack to build your library, you’ll need to run ngc first and then run webpack on the compiled code. This issue is tracking changes needed to have webpack manage the whole process. This repo is an example of using the npm run ngc && npm run webpack strategy.

7. Test the new package in an AoT enabled starter

I’ve used angular2webpack2-starter, but there are several others. Here are my steps:

  1. In your compiled library directory, run npm pack. This will create your-awesome-library.tar.gz
  2. Somewhere else, run git clone https://github.com/qdouble/angular2webpack2-starter.git
  3. cd angular2webpack2-starter && npm install
  4. npm install ../path/to/your-awesome-library.tar.gz
  5. Import your library into AppModule in src/app/app.module.ts, and test your library functionality somehow.
  6. npm run compile:aot && npm run prodserver
  7. Go to http://localhost:8088 to see the results

8. Publish your library to npm

9. Listen to the applause from your adoring user base