Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Webpack, Typescript and Angular2 with Ahead Of Time (AOT) compilation?

The latest release of Angular2 allows for Ahead of time (AOT) compilation, using this code in your app.bootstrap.ts file:

// The browser platform without a compiler
import { platformBrowser } from '@angular/platform-browser';

// The app module factory produced by the static offline compiler
import { AppModuleNgFactory } from './app.module.ngfactory';

// Launch with the app module factory.
platformBrowser().bootstrapModuleFactory(AppModuleNgFactory);

Angular2 Official Documentation

How can we integrate Webpack and Typescript loaders with Angular2's AOT compiler?

It seems there might not be an option to do so yet, but I'm asking the question on Stack overflow so when it is available, the answer can be easily found.

UPDATE 10/12/16 - I got it working, see my answer below.

like image 787
TetraDev Avatar asked Aug 23 '16 21:08

TetraDev


People also ask

What would you use ahead-of-time AOT compilation?

The Angular ahead-of-time (AOT) compiler converts your Angular HTML and TypeScript code into efficient JavaScript code during the build phase before the browser downloads and runs that code. Compiling your application during the build process provides a faster rendering in the browser.

What are the ways to control AOT compilation?

When you use the Angular AOT compiler, you can control your app compilation in two ways: By providing template compiler options in the tsconfig. json file. By specifying Angular metadata.

What is the time to load bootstrap in AOT?

Total time to bootstrap The AOT version of our application took 2,602ms to load and bootstrap, while the JIT version took 4,804ms. If we look at the “content breakdown” of each test, we can see that the AOT version has 101KB of JS (gzip), while the non-AOT version has 190KB (gzip).

What is the difference between JIT and AOT in Angular?

JIT downloads the compiler and compiles code exactly before Displaying in the browser. AOT has already complied with the code while building your application, so it doesn't have to compile at runtime. Loading in JIT is slower than the AOT because it needs to compile your application at runtime.


1 Answers

I got it working finally, see my repo Angular2 Webpack2 DotNET Starter

There are several tricks necessary. Note that AOT compilation does not support any require() statements in your Angular 2 components. They will need to be converted to import statements.

First, you need to have a second tsconfig.json file, with special options for AOT compilation. I designate this with .aot.json extension.

tsconfig.aot.json :

{
   "compilerOptions": {
      "target": "es5",
      "emitDecoratorMetadata": true,
      "experimentalDecorators": true,
      "allowSyntheticDefaultImports": false,
      "noEmitHelpers": true,
      "pretty": true,
      "strictNullChecks": false,
      "baseUrl": ".",
      "sourceMap": true,
      "sourceRoot": ".",
      "lib": [
         "es6",
         "dom"
      ],
      "types": [
         "lodash",
         "hammerjs",
         "jasmine",
         "node",
         "selenium-webdriver",
         "source-map",
         "uglify-js",
         "webpack",
         "materialize-css",
         "jquery",
         "kendo-ui"
      ],
      "typeRoots": [
         "./node_modules/@types"
      ],
      "outDir": "./compiled/src"
   },
   "exclude": [
      "./node_modules",
      "./**/*.e2e.ts",
      "./**/*.spec.ts",
   ],
   "awesomeTypescriptLoaderOptions": {
      "useWebpackText": true,
      "forkChecker": true,
      "useCache": true
   },
   "compileOnSave": false,
   "buildOnSave": false,
   "atom": {
      "rewriteTsconfig": false
   },
   "angularCompilerOptions": {
      "genDir": "./compiled/aot",
      "debug": true
   }
}

You'll also need the exact right combination of verions of Angular2. @angular/[email protected] and @angular/[email protected] did NOT work for me, I had to use 2.0.0 for both or ngc failed to compile the AOT files. Here's what I'm using successfully:

package.json :

  "dependencies": {
    "@angular/core": "2.0.0",
    "@angular/common": "2.0.0",
    "@angular/compiler": "2.0.0",
    "@angular/compiler-cli": "0.6.2",
    "@angular/forms": "^2.0.1",
    "@angular/http": "2.0.0",
    "@angular/platform-browser": "2.0.0",
    "@angular/platform-browser-dynamic": "2.0.0",
    "@angular/platform-server": "2.0.0",
    "@angular/router": "3.0.0",
    "@angular/tsc-wrapped": "0.3.0"
}

In addition, you'll need a couple nifty webpack loaders, while also allowing webpack to look in the ./src folder as well as the folder your AOT compiled files are output to. (*.component.ngfactory.ts)

That last part is very important! If you don't tell webpack to include it those folders, it won't work. In this example, the AOT files are output to /aot-compiled in the root folder.

webpack.common.js

  loaders: [
     {
        test: /\.ts$/,
        include: [helpers.paths.appRoot, helpers.root('./compiled/aot')],
        exclude: [/\.(spec|e2e)\.ts$/],
        loaders: [
           '@angularclass/hmr-loader',
           'awesome-typescript-loader',
           'angular2-template-loader',
           'angular2-router-loader?loader=system',
           "angular2-load-children-loader" // this loader replaces loadChildren value to work with AOT/JIT
        ],
     },
  ]

To generate your AOT files, you'll need an NPM script to do it for you

package.json

   "scripts": {
      "compile:aot": "./node_modules/.bin/ngc -p ./tsconfig.aot.json",
   }

You'll also need to make your webpack config read the AOT version of app.bootstrap.ts - which is different from the JIT version. I differentiate it with .aot.ts extension so that in production, webpack uses AOT (app.bootstrap.aot.ts), but in dev mode, it uses JIT with webpack-dev-server (app.bootstrap.ts).

Finally, you run npm run compile:aot FIRST. Once your AOT files are output to disk, you run your webpack build with either webpack or webpack-dev-server.

For a working example, see my repo Angular2 Webpack2 DotNET Starter. It's integrated with .NET Core 1.0, but for those not using .NET, you can still see how Webpack 2 and Angular 2 are configured.

like image 88
TetraDev Avatar answered Nov 10 '22 00:11

TetraDev