In the context of technology and software development, bootstrapping is the process of initializing and setting up a system or application from scratch. It's like laying the foundation and getting everything ready for the system to run smoothly.
In Angular, it is the process of initializing or starting up an Angular application. It's like flicking the switch that brings your Angular project to life.
When you bootstrap an Angular application, you're starting it up and making it work. Angular takes charge, sets everything up, connects all the pieces, and prepares your app for running smoothly.
Getting too worked up with the technical jargon and confused about how it all works behind the scenes. Trust me I've been there. No worries it's time for the DEEP DIVE😁.
Deep Dive: Initialized! Beep Boop Beep Boop
Let's start by creating a new angular application from scratch and then surgically bifurcate it piece by piece.
ng new BootstrappingBlog
You can run the following application using
ng serve --open
Voila!!! Your app is running. So till now you've created a new angular app and run it into the browser. Now as promised let's take a look at how the page which you see above was loaded. Let's goooo🚀🚀.
Angular takes the following steps in sequence(very important) to load our first view.
The index.html file is loaded.
Angular framework and any third-party libraries used in the application are loaded.
The entry point of the application, typically main.ts, is executed.
The root module, defined in app.module.ts, is loaded and executed.
The root component, specified in app.component.ts, is executed.
1. Initial Loading: index.html
Every web application requires a starting point, and in the case of Angular, that starting point is usually the index.html file. This file serves as the initial page that gets loaded when the application is accessed. To locate the index.html file, you can navigate to the "src" folder of your Angular project.
Now let's look at what the heck is actually inside this index.html file. Ready??***Drumroll***🥁
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>BootstrapingBlog</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
</html>
oh oh. That's a bummer. The page which we saw getting loaded was so different from what we see here. Isn't it? Let's compare the page which got loaded with this index.html file.
See, this contains lots of text, icons, and buttons and it looks pretty. But the index.html doesn't have:
Most of the text that you see here on the screen.
Any mention of the CSS stylesheet to have all the CSS effects which we observe on the screen.
Any mention of the Javascript script required for the functioning of the page.
All we see is a strange HTML tag.
<app-root></app-root>
How does angular load all of the content of the page? To find out, let us build our application.
Now some questions that might arise for you are:
What do you mean by building the application?
Why are we doing it now? Why didn't we do it earlier?
Do building an application and running the application mean different things?
Let's answer each question one by one.
What do you mean by building the application?
Building an Angular app refers to the process of compiling and generating the production-ready files for the application. When we build an Angular app, the code is transformed and optimized for deployment.Why are we doing it now? Why didn't we do it earlier?
Earlier our goal was to simply run the application on our localhost, we did not intend to create a code that would be suitable for deployment. Hence, we did not explicitly build the application earlier.Do building an application and running the application mean different things?
While running the app withng serve
, the application files are not optimized or minified, and the compiled code is stored in memory rather than saved to the disk. Since the compiled code is not stored on the disk, hence we see the uncompiled version of the index.html file without any stylesheet or script.When we build an Angular app using
ng build
, the code is transformed and optimized for deployment, resulting in a set of static files that can be served by a web server. The output of the build process is a set of static files stored on the disk and can be located in thedist
folder.Hence, to view the compiled application, we need to build the project. We can do that using the
ng build
. Open the command prompt and run theng build
command. This will build and copy the output files to thedist
folder.Building an Angular Application
To build an angular application we use the
ng-build
command.ng-build
The output of the build process is a set of minified static files that can be located in the
dist
folder.You can see that the compiler included four script files. They are
runtime
,polyfills
,styles
, andmain
along with a compiled version of the index.htmldist/boostraping-blog/index.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>BootstrapingBlog</title> <base href="/"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" type="image/x-icon" href="favicon.ico"> <link rel="stylesheet" href="styles.ef46db3751d8e999.css"> </head> <body> <app-root></app-root> <script src="runtime.71617b7d37dc8d33.js" type="module"></script> <script src="polyfills.3682be9b3ef37bf9.js" type="module"></script> <script src="main.c77b08b870779a1b.js" type="module"></script> </body> </html>
runtime.js:
Webpack runtime file.polyfills.js:
Polyfill scripts for supporting the variety of the latest modern browsers.styles.js:
This file contains the global style rules bundled as a javascript file.main.js:
Actual code of the application.
This index.js file is loaded now and it contains information about the styles of the applications(styles.js) and the remaining HTML and Javascript code(main.js).
2. Loading Angular framework and any third-party libraries
When the index.html file is loaded, it triggers the loading of the Angular Core Framework and any other third-party libraries that are necessary for the application. These libraries are essential for the functioning of the Angular application and provide various features and functionalities. By including them in the initial loading process, the application ensures that all the required dependencies are available and ready for use.
3.Entry Point of Application
The entry point of an Angular application is the main.ts file. In the main.ts file, several important tasks are performed. It imports the necessary modules and dependencies required by the application. It also contains the bootstrap function, which initializes and launches the Angular application.
How does angular know that the entry point is main.ts?
To determine the entry point of an Angular application, Angular looks for the configuration file called angular.json
. This file resides in the root folder of the project and holds various settings and configurations for the Angular project.
The relevant part of the angular.json
is shown below.
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"BootstrapingBlog": {
"projectType": "application",
"schematics": {},
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/bootstraping-blog",
"index": "src/index.html",
"main": "src/main.ts",====================> Main.ts
"polyfills": [
"zone.js"
],
....... Rest of the file
The "main" entry under the node projects -> BootstrapingBlog -> architect -> build -> options -> main points towards the src/main.ts. This file is the entry point of our application.
Now that we understand how Angular determines the entry point of an application, let's take a closer look at what happens when Angular loads and executes the main.ts file. Let's dive a little deeper into the main.ts file itself.
main.ts
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));
Let's breakdown the code:
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
This line imports the module platformBrowserDynamic
from the library@angular/platform-browser-dynamic
.
Now, the obvious question would be what is this platformBrowserDynamic
Module? What's the use of it? Let's answer all of these questions now.
What is platformBrowserDynamic
platformBrowserDynamic
is the module responsible for loading the Angular application in the desktop browser.
In Angular, we have the flexibility to bootstrap our applications on various platforms. When it comes to loading an Angular application in a desktop browser, the responsible module is called platformBrowserDynamic
.
This module, aptly named, is specifically designed for the desktop browser environment. It enables us to dynamically load and run our Angular application within the browser. By using the platformBrowserDynamic
module, we can invoke the bootstrapModule
method, passing in our root module (typically AppModule), to initiate the application's execution.
On the other hand, if we are working with NativeScript—a framework for building native mobile applications—we follow a slightly different approach. In this case, we utilize the platformNativeScriptDynamic
module from the nativescript-angular/platform
library. To bootstrap our application, we invoke the platformNativeScriptDynamic().bootstrapModule(AppModule)
method instead.
import { AppModule } from './app/app.module';
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));
The first line imports AppModule
, which serves as the root module of the Angular application. In Angular, applications are organized into modules, and every Angular application must have at least one module. The root module is the module that is loaded first when the application is launched.
The platformBrowserDynamic()
loads the root module by invoking the bootstrapModule method and giving it the reference to our Root module i.e. AppModule.
4.Executing the Root Module(AppModule)
The angular bootstrapper, represented by the code platformBrowserDynamic().bootstrapModule(AppModule)
, takes charge of loading our root module called AppModule
. This special module acts as the foundation of our application and is located within the src/app
folder.
Let's look at what's inside app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
The root module must have at least one root component. The root component is loaded when the module is loaded by Angular.
In our example, AppComponent
is our root component. Hence we import it.
import { AppComponent } from './app.component';
We use @NgModule
class decorator to define an Angular Module and provide metadata about the Modules.
Confused 😕😕??
Decorators? MetaData? What's all this. Let's answer these questions now.
Decorators:
Everything in angular is a class, be it component, module, directives, pipes everything is a class. The only way angular differentiates between them is through the Decorator we provide to that class.@Component
angular will treat this class as a component
@NgModule
angular will treat this class as a module
@Directive
angular will treat this class as directive
@Pipe
Angular will treat this class as pipe
if no Decorator is provided angular will treat that class as simple typescript class.
MetaData:
Ok so we've seen angular uses Decorators to treat classes differently. The purpose of these Decorators is to provide some additional information about these classes to Angular, so that angular can decide how to process these classes(as component, module, pipes, directives).
The additional information which these Decorators provides to angular about the classes is called MetaData.
The @NgModule has several metadata properties.
Imports
We need to list all the external modules required, including other Angular modules used by this Angular Module.
Declarations
The Declarations array contains the components, directives, & pipes that belong to this Angular Module. We have only one component in our application. AppComponent
.
Providers
The Providers array is where we register the services we create. The Angular dependency injection framework injects these services into components and directives. pipes and other services.
Bootstrap
The component that angular should load when this Angular Module loads. The component must be part of this module. We want AppComponent
load when AppModule
loads, hence we list it here.
The Angular reads the bootstrap metadata and loads the AppComponent
.
5.Executing the Root Component(AppComponent)
Pheww!!! It's been long, isn't it? Finally, we arrived at a place where you'll be able to map things to the first page that was loaded.
Let's first understand the code of AppComponent. Then things will automatically start to come together. You can locate it under src/app.
app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'BootstrapingBlog';
}
@Component
signifies that this particular class will be considered as Component.
The @Component has several metadata properties:
selector
The selector is like a name tag for our component. It's a unique identifier that Angular uses to recognize and render our component within the HTML structure. In this case whenever angular sees <app-root></app-root>
inside any HTML Structure , it understand that at this place it have to load the HTML content of AppComponent.
Now, you might wonder, how does Angular know what HTML content to display for the AppComponent? That's where the templateUrl metadata property comes into play.
templateUrl
The templateUrl property provides the path to an HTML file that holds the structure and content of the component. It's like a map that guides Angular to the specific HTML file associated with the component. Angular retrieves the HTML content from that file and dynamically inserts it into the designated place in the HTML structure where the component's selector tag (<app-root></app-root>
) is present.
The templateUrl for app component is './app.component.html'. That means wherever the <app-root></app-root>
would be present, angular will display the content of app.component.html.
The Fancy page which you saw when we ran our application, that was app.component.html.
styleUrls
Just like the templateUrl property tells angular the path to the HTML file for the component, the styleUrls provides the path to an CSS file that holds the stylesheet of the component.
The styleUrl for app component is './app.component.css'. That means wherever the <app-root></app-root>
would be present, angular will apply the above stylesheet on app.component.html.
Summary: Joining the DOTS
Phewwww!!! It's been long ⌚. We have explored the individual steps that Angular takes to load our first view in detail. Now, let's connect those steps together to get a complete picture of how it works.
When we start our Angular application using the
ng serve
command, Angular goes through a series of steps to load and display our first view.It all begins with the
index.html
file, which serves as the entry point of our application. Angular sees a special tag<app-root></app-root>
inside index.html.Once it sees the
<app-root></app-root>
it determines that it has to load app.component.html along with app.component.css stylesheet.
Hence, when we run our Angular application for the first time, we see a fancy introductory page by default. This pre-designed page is created by the Angular development team to provide a pleasant starting point for our application.
You can override the contents of app.component.html and app.component.css with your own custom markup and styles.