The process of loading the index.html page, app-level module, and app-level component is called bootstrapping, or loading the app. In this guide, you will learn about the internals of the bootstrapping process.
Angular takes the following steps to bootstrap the application:
The starting point of any Angular web application is the index.html page. This page refers to all the necessary JavaScript files for the application. If you examine the index.html file after building an Angular project, you will find that it has references to the JavaScript files, as shown below:
1<!doctype html>
2<html lang="en">
3<head>
4 <meta charset="utf-8">
5 <title>GettingStarted</title>
6 <base href="/">
7 <meta name="viewport" content="width=device-width, initial-scale=1">
8 <link rel="icon" type="image/x-icon" href="favicon.ico">
9</head>
10<body>
11 <app-root></app-root>
12
13 <script src="runtime-es2015.js" type="module"></script>
14 <script src="runtime-es5.js" nomodule defer></script>
15 <script src="polyfills-es5.js" nomodule defer></script>
16 <script src="polyfills-es2015.js" type="module"></script>
17 <script src="styles-es2015.js" type="module"></script>
18 <script src="styles-es5.js" nomodule defer></script>
19 <script src="vendor-es2015.js" type="module"></script>
20 <script src="vendor-es5.js" nomodule defer></script>
21 <script src="main-es2015.js" type="module"></script>
22 <script src="main-es5.js" nomodule defer></script></body>
23</html>
You will notice that there are two versions of each file:
main.js
has the application code in it.
The code inside the main.js
file is the entry point for the application. This file imports the module platformBrowserDynamic
from the library @angular/platform-browser-dynamic
. platformBrowserDynamic
is the module responsible for loading the Angular app in the desktop browser. Similar to this module, the module platformNativeScriptDynamic
loads the app in a mobile device. Angular is flexible enough to run in a browser, server, web-worker, or mobile device.
When bootstrapModule(AppModule, options)
is called, it compiles the AppModule
in the first step.
The code for the bootstrapModule
function is as follows:
1bootstrapModule<M>(moduleType: Type<M>, options: CompilerOptions): Promise<NgModuleRef<M>> {
2
3 return compileNgModuleFactory(this.injector, options, moduleType)
4 .then((moduleFactory: NgModuleFactory) => {
5
6 // ...
7 });
8}
You will notice that the bootstrapModule
is calling compileNgModuleFactory
, which has the following code:
1function compileNgModuleFactory<M>(
2 injector: Injector,
3 options: CompilerOptions,
4 moduleType: Type<M>
5 ): Promise<NgModuleFactory<M>> {
6
7 const compilerFactory: CompilerFactory = injector.get(CompilerFactory);
8 const compiler = compilerFactory.createCompiler([options]);
9 return compiler.compileModuleAsync(moduleType);
10}
First of all, it retrieves an instance of CompilerFactory
from the injector. CompilerFactory
is an abstract class that is responsible for the creation of an instance of the compiler. If the Angular app is running in dev mode, then an instance of JitCompiler
is created that has the following code:
1export class JitCompiler {
2
3 private compileModuleAsync(moduleType: Type): Promise<NgModuleFactory> {
4
5 return this._loadModules(moduleType)
6 .then(() => {
7 this._compileComponents(moduleType);
8 return this._compileModule(moduleType);
9 });
10 }
11}
You will notice that it is loading all the modules, directives, and pipes metadata. Then, it compiles all the components. During the compilation of the components, it searches for all component metadata registered in the app and asks the compiler to compile all component templates in one place. The last thing it does is to actually compile the app-level module. At this stage, Angular resolves all the required metadata for the module and returns the module factory.
Before bootstrapping the Angular app, platformBrowserDynamic
needs to create a root NgZone
. Root NgZone
has to be instantiated even before AppModule
creation, because all the app logic has to be wrapped inside the root zone.
When the root NgZone
creation is complete, the platformBrowserDynamic
instantiates the app-level module through the root module factory created as a result of the module compilation step.
Every Angular app has at least one module. The module that is loaded first when the app is loaded is called the app-level module or root module. platformBrowserDynamic
bootstraps the app-level module by invoking the bootstrapModule
function and giving it the reference to your app-level module, i.e AppModule
.
The app-level module or root module has one app-level component or root component. This app-level component or root component is loaded when the app-level modules are loaded by Angular. Apart from the app-level component, this module also has reference to all external modules imported using the imports
array. The module also has reference to all the services that needsto be loaded as singletons and will be available across the app.
The bootstrap
property or key of the NgModule
decorator specifies which component should be loaded by Angular when the app-level module loads. Angular reads the bootstrap metadata and loads the app-level component, called AppComponent
.
The TypeScript class of the app-level component, called AppComponent
, is decorated with the @Component
class decorator. The @Component
class decorator provides the metadata about the class to Angular. It has the following three properties:
If you are injecting a service into this component, then you will have a fourth property, as well, that references the service that will be injected into this class's constructor. The fourth property is called providers
. It is an array of service classes that will be injected into this component.
The templateURL
property points to the HTML template file, which will be rendered to the browser when this component is processed. The selector
property specifies the CSS selector, where the template will be inserted into the HTML.
Once platformBrowserDynamic
is done with all preparation, it is ready to instantiate the app-level component or root component. platformBrowserDynamic
then just iterates through the bootstrap components array and asks ApplicationRef
to actually bootstrap each component.
Congratulations! You have learned about the internals of Angular's bootstrap process. For more information, please refer to bootstrapping in Angular.