Книга: Angular 2 Cookbook
Назад: Configuring the Angular 2 Renderer to use web workers
Дальше: Configuring an application to use lazy loading

Configuring applications to use ahead-of-time compilation

Angular 2 introduces the concept of ahead-of-time compilation (AOT). This is an alternate configuration in which you can run your applications to move some processing time from inside the browser (referred to as just-in-time compilation or JIT) to when you compile your application on the server.

Note

The code, links, and a live example related to this recipe are available at .

Getting ready

AOT compilation is application-agnostic, so you should be able to add this to any existing Angular 2 application with minimal modification.

For the purposes of this example, suppose you have an existing AppModule inside app/app.module.ts. You needn't concern yourself with its content since it is irrelevant for the purpose of AOT.

How to do it...

Using AOT means you will compile and bootstrap your application differently. Depending on how it is configured, you will probably want to use sibling files with "aot" added to the name. Bear in mind that this is only for organizational purposes; Angular is not concerned with what you name your files.

Installing AOT dependencies

Angular requires a new compilation tool ngc, which is included in the @angular/compiler-cli package. It will also make use of platformBrowser to bootstrap, which is provided inside the @angular/platform-browser package. Install both of these and save the dependency to package.json:

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

Configuring ngc

ngc will essentially perform a superset of duties of the tsc compilation tool you are accustomed to using. It is wise to provide it with a separate config file, which can be named tsconfig-aot.json (but you are not beholden to this name).

The file should appear identical to your existing tsconfig.json file but with the following important modifications:

[tsconfig-aot.json]      {     "compilerOptions": {       (lots of settings here already, only change 'module')       "module": "es2015",   },     "files": [       "app/app.module.ts",      "main.ts"     ],     "angularCompilerOptions": {      "genDir": "aot",      "skipMetadataEmit" : true   } } 

Aligning component definitions with AOT requirements

AOT compilation requires your application to be organized in a few specific ways. Nothing should break an existing application, but they're important to do and take note of. If you've been following Angular best practices, they should be a breeze.

First, component definitions must have a moduleId specified. You will find that components generated with the Angular CLI already have this included. If not, the moduleId should always be module.id, as shown here:

@Component({     moduleId: module.id,     (lots of other stuff)   })   

Since the module is undefined when compiling in AOT, you can provide a dummy value in the root template:

<script>window.module = 'aot';</script>   

Tip

AOT doesn't need the module ID, but it allows you to have a compilation without errors. Note that these steps involving moduleId may be changed or eliminated entirely in future versions of Angular, as they only exist to allow you to have compatibility between both JIT and AOT compilations.

Next, you'll need to change the path of the templates, both CSS and HTML, to be relative to the component definition file, not application-root-relative. If you are using the convention given by the Angular CLI or the style guide, you are probably already doing this.

Compiling with ngc

ngc isn't available directly on the command line; you'll need to run the binary file directly. Additionally, since in this example it's not using the tsconfig.json naming convention, you'll need to point the binary to the location of the alternate config file. Run the following command from the root of your application to execute the compilation:

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

This command will output a collection of NgFactory files with .ngfactory.ts inside the aot directory, as you specified earlier in the angularCompilerOptions section of tsconfig-aot.json.

The compilation is done, but your application doesn't yet know how to use these NgFactory instances.

Bootstrapping with AOT

Your application will now start off with AppModuleNgFactory instead of AppModule. Bootstrap it using platformBrowser:

[main.ts]      import {platformBrowser} from '@angular/platform-browser';   import {AppModuleNgFactory} from 'aot/app/app.module.ngfactory';      platformBrowser().bootstrapModuleFactory(AppModuleNgFactory);   

With this, you'll be able to run your application normally but this time using precompiled files.

How it works...

Compiling in Angular is a complex subject, but there are several main points relevant to switching an application to an AOT build process:

  • The Angular compiler lives inside the @angular/compiler module, which is quite large. Using AOT means this module no longer needs to be delivered to the browser, which yields substantial bandwidth savings.
  • The Angular compilation process involves taking the template strings inside your components, which exist as defined by template or templateUrl, and converting them into NgFactory instances. These instances specify how Angular understands how you defined the template. The conversion to Factory instances happens both in JIT and AOT compilation; switching to AOT simply means you are doing this processing on the server instead of the client and serving NgFactory definitions directly instead of uncompiled template strings.
  • AOT will obviously slow down your build time since more computation is required each time the code base needs updating. Since you can trust that Angular will be able to correctly interpret NgFactory definitions that the AOT compilation generates, it is best to do JIT compilation when developing the application and AOT compilation when building and deploying production applications.

There's more...

AOT is cool, but it might not be for everybody. It will very likely reduce the load time and initialization time of your Angular application, but your build process is considerably more involved now. What's more, if you want to use JIT in development but AOT in production, you now have to maintain two versions of three different files: index.html, main.ts, and tsconfig.json. Perhaps this additional build complexity overhead is worth it, but it should certainly be a judgment call based on your development situation.

Going further with Tree Shaking

Angular also supports a separate step of optimization called Tree Shaking. This uses a separate npm library called rollup. Essentially, this library reads in your entire application (as JS files), figures out what modules are not being used, and cuts them out of the compiled codebase and therefore of the payload that is delivered to the browser. This is analogous to shaking a tree to make the dead branches fall out, hence "tree shaking."

Note

The es2015 module configuration specified earlier in tsconfig-aot.json was for supporting the rollup library, as it is a requirement for compatibility.

If your application code base is well-maintained, you will most likely see limited benefits of tree shaking since unused imports and the like will be caught when coding. What's more, one could make the argument that tree shaking might be an anti-pattern since it subtly encourages a liberal use of module inclusion by the developer with the knowledge that tree shaking will do the dirty working of cutting out any unused modules. This may then lead to a cluttered code base.

Using tree shaking can be a useful tool when it comes to Angular 2 applications, but its usefulness is in many ways evaporated by keeping a code base tidy.

See also

  • Understanding and properly utilizing enableProdMode with pure and impure pipes describes how to take the training wheels off your application
  • Configuring the Angular 2 renderer service to use web workers guides you through the process of setting up your application to render on a web worker
  • Configuring an application to use lazy loading shows how you can delay serving chunks of application code until needed
Назад: Configuring the Angular 2 Renderer to use web workers
Дальше: Configuring an application to use lazy loading

thank you
Flame
cant read the code since it is all on a single line. Also this comments section is russian
Rakuneque
DATA COLLECTION AND ANALYSIS Two reviewers extracted data and assessed methodological quality independently lasix torsemide conversion Many others were in that space already