Angular Platforms in depth. Part 2. Application bootstrap process

Nikita Poltoratsky
Angular In Depth
Published in
4 min readJul 10, 2019

AngularInDepth is moving away from Medium. This article, its updates and more recent articles are hosted on the new platform inDepth.dev

The Angular framework was designed with flexibility in mind. That approach allows Angular applications to be executed across different environments — browser, server, web-worker, and even mobile devices are possible.

In this series of articles, I’m going to reveal to you how does it even possible — execute Angular applications across different environments. Also, we’ll learn how to build custom Angular platform which renders applications inside the system’s terminal using ASCII graphics.

Articles:

Each Angular application starts with the main.ts file:

Here, you could notice that we’re creating a new instance of PlatformRef and then calling bootstrapModule method on it. It’s a place where Angular application starts. In this article, we’re going to dive deeper into the application bootstrap process.

If you want to learn more on what are Angular platforms and how are they created, please, check previous article from the series: Angular Platforms in depth. Part 1. What are Angular Platforms?

As I stated previously, each Angular application starts with the following call

platformRef.bootstrapModule(AppModule) 

Here is the full code of bootstrapModule method:

Let’s discuss it step by step.

Table of contents

  • Module Compilation
  • Root NgZone
  • Error handling
  • Initializers
  • Bootstrap components

Module Compilation

The first step in the application bootstrap process is a module compilation.

So, when we’re calling bootstrapModule(AppModule, options) on PlatformRef first of all, it compiles that module. Here, moduleType refers to the AppModule. The injector is just an instance of Injector injected through constructor. And options are compiler options provided as the second argument into bootstrapModule method.

Let’s dive deeper at the compileNgModuleFactory function to learn more about the module compilation process.

First of all, Angular retrieves an instance of CompilerFactory from the injector. CompilerFactory is an abstract class which is responsible for the creation of an instance of the Compiler. For instance, when we’re starting Angular application in dev mode, then JitCompilerFactory implementation will be provided. Then, JitCompiler implementation of the Compiler will be created as a result of compilerFactory.createCompiler() function call. Then, compiler is asked to compiler our AppModule.

Here, Angular loads all the modules, directives and pipes metadata. Then, it compiles all the components. During the compilation of the components, it searches for all components metadata registered in the application, then asks the compiler to compile all component’s templates in place. The last thing we need to do here is to actually compile the root application module. On that stage, Angular resolves all the required metadata for the module and return module factory.

When module compilation is done, PlatformRef has moduleFactory and can start the bootstrap process.

Root NgZone

Before actually bootstrapping Angular application PlatformRef need to create a root NgZone.

Root NgZone has to be instantiated even before AppModule creation, because we need to wrap all the application logic inside the zone. Meanwhile, during creation Angular modules may create some providers eagerly, that’s why even root module creation logic has to be wrapped into the zone.

And only when the root NgZone created PlatformRef could instantiate the root module through the root module factory created as a result of the module compilation step.

Error handling

When root NgZone created and root module already instantiated it’s time to set up a global error handler:

ErrorHandler in Angular, is responsible for proper errors logging and handling. So, to set up ErrorHandler PlatformRef need to retrieve provided ErrorHandler from the injector. Then, subscribe to errors stream from the root zone and call handlerError method as a reaction for each error event.

But look, all the error handling logic is wrapped in zone.runOutsideAngular function. That function makes sure that any code executed inside will never trigger a change detection run.

Initializers

When ErrorHandler set up, it’s a time to run application initializers.

Here, Angular uses ApplicationInitStatus entity to run application initializers. Application initializers are just functions, which execution required to be done right before the application bootstrap. For instance, the web worker platform has the following initializer:

{provide: APP_INITIALIZER, useValue: setupWebWorker, multi: true}

So, application initializers are just functions that provided under APP_INITIALIZER token. Then, all APP_INITIALIZER tokens injected into ApplicationInitStatus using the following statement:

constructor(@Inject(APP_INITIALIZER) private appInits: (() => any)[]) {

When runInitializers method called it just execute all the app initializers and return the result using Promise.all().

Bootstrap components

Ok, on that stage PlatformRef is done with all preparations and ready to actually bootstrap AppComponent! As you remember, above we’ve seen how to root module instance was created:

const moduleRef = moduleFactory.create(this.injector);

Each root Angular module has to contain bootstrap components array:

PlatformRef then just iterates through that bootstrap components array and asks ApplicationRef to actually bootstrap each component:

ApplicationRef inside just creates and renders components:

The code above has to be familiar for those of you who created some Angular components dynamically. Here, we could notice how ComponentFactoryResolver utilized to resolve componentFactory for AppComponent and then just creates it.

And that’s it! We did it! On that stage, we have AppComponent rendered on the screen, which will render all the rest parts of the application.

Conclusion

Congratulations 🥳 you’ve reached the end of the article. During the article, we went through the application bootstrap process. And now we have all the required knowledge to start building our custom platform which will render Angular applications inside the system’s terminal using ASCII graphics.

If you want to get deeper knowledge on Angular platforms, take a look at the rest articles of the series:

Also, follow me on twitter to be notified about new Angular articles as soon as possible!

--

--

Nikita Poltoratsky
Angular In Depth

Developer Advocate at Akveo · Tech Author · Nebular and Ngx-Admin team · Minsk, Belarus