Bundling an Angular 2/4 app with AOT Compilation


Prerequisite :

  1. Good knolwledge of Angular 2/4
  2. Basic knowledge of gulp.

Step 1 :

Ahead-of-Time(AOT) Compilation :
Angular application consists of components and their html templates. To run them on browser, they are compiled to executable javascript by the angular compiler. One option is to compile them on browser at runtime using just-in-time(JIT) compiler. It’s good for development environment, but it has shortcomings.

JIT compilation incurs a runtime performance penalty. Views take longer to render because of the in-browser compilation step. The application is bigger because it includes the Angular compiler and a lot of library code that the application won’t actually need. Bigger apps take longer to transmit and are slower to load.

Also, while compiling at runtime on browser, all the template binding errors will occur on browser only.

Coming to the other and better option, AOT compilation.
AOT improves performance by compiling at build time and hence find template errors early as well.

Here are some advantages of AOT compilation

  • Faster rendering
  • Fewer asynchronous requests
  • Smaller Angular framework download size
  • Detect template errors earlier
  • Better security

How to compile the app with ngc compiler :

We will use ngc compiler provided in the @angular/compiler-cli. To install it, run :

npm install @angular/compiler-cli @angular/platform-server --save

ngc requires its own tsconfig.json with AOT-oriented settings. We add tsconfig-aot.json with the following code :

angularCompilerOptions :
“genDir” : specifies the directory for compiled code
“skipMetadataEmit” : true : property prevents the compiler from generating metadata files

To compile your code, run :

node_modules/.bin/ngc -p tsconfig-aot.json

What it does, is first creare ngFactory.ts files in dist/aot(specified in genDir) , then again transpiles it again to ngFactory.js using compilerOptions.

After compilation, you can see NgFactory files in the folder specified in genDir. Each component factory creates an instance of the component at runtime by combining the original class file and a JavaScript representation of the component’s template.

Note : JIT compilation also generates these same NgFactories in memory where they are largely invisible.

Now, instead of bootstrapping AppModule, we will bootstrapp the AppModuleNgFactory. Add boot-aot.ts, with the following code :


Note : In tsconfig.json, add boot-aot.ts to "exclude", so that it won't compile while you run your typescript compiler. Otherwise it will show error that, AppModuleNgFactory not found.

Step 2 :

Tree Shaking

A tree shaker walks the dependency graph, top to bottom, and shakes out unused code like dead leaves in a tree.

We are going to use a tree shaking utility called Rollup.

Rollup statically analyzes the application by following the trail of import and export statements. It produces a final code bundle that excludes code that is exported, but never imported. Rollup works on only ES2015, and that’s the reason we specified module as ES2015 in our tsconfig-aot.json.

Add the following dependencies :

npm install rollup rollup-plugin-node-resolve rollup-plugin-commonjs rollup-plugin-uglify --save-dev

Create a rollup-config.js and add the following code :

entry: the App entry point.
dest: this attribute tells Rollup to create a bundle called build.js in the dist folder.
format: Rollup supports several output formats. Since we’re running in the browser, we want to use an immediately-invoked function expression (IIFE).

For rollup, Run :

node_modules/.bin/rollup -c rollup-config.js

Step 3 :

Remove moduleId : module.id :

In Angular, for each component we add some metadata to it, one of that is moduleId. By specifying moduleId, we tell the component that its templates and styles are in the current folder. Since we compiled the bundle with aot, all the templates and css gets inlined to the js files, so we need to remove the moduleId property.

Add a new task in gulpfile, as follows :

Run :

gulp tweak-minJs

Note : To install any gulp dependency, run the following command :
$ npm install --save-dev

Step 5 :

Vendor all assets :

Next we need to get assets from the development folder and put them corresponding to your production bundle. We will again use gulp for this.

Vendor css files
Add the following code in gulpfile.js

Vendor JS files

To concatenate, all javascripts files to a single javascript file, add the following code to your gulpfile.js

If you just want them to be copied, and not get concatenated, you can add the following code :

Similarly, we copy fonts and other assets that we need.


Step 5 :

Minify Images :

Next we will minify all our images used in the website. Here’s the gulp code :

Step 6 :

Add index.html

Change your index.html name to index-jit.html, now this index-jit.html we will use for development. And add a new index.html file with same content. This index.html we will use in production mode.

Update your index.html as follows :
Remove this code :

And Add :

Since we have created the precompiled bundle that is ready to for browser, all we need it to include that, we no longer need systemjs.config.js to load our application. You can either just add a script tag to add your js bundle, or you can follow the above code to add your bundle which disable caching of your bundle on browser. Disabling cache is only required if you constantly change your Application.

Next we need to copy our index.html to our production folder, and add our vendor js and vendor css files to it.

Add the following gulp code :


Step 7 :

Copy remaining assets

Step 9 :

GZIP :
The 9th and final step is to compress your bundle and vendor js and vendor css. We will use gulp-gzip dependency for this.

Reference : https://angular.io/guide/aot-compiler

Advertisements
This entry was posted in Scala. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s