Just want to learn how Angular builds and runs behind the scenes?
Below is what I understood thus far. Want to know if I missed something.
How Angular builds
After coding our Angular apps using TypeScript, we use the Angular CLI command to build the app.
ng build
command compiles the application into an output directory and the build artifacts will be stored in the dist/
directory.
Internal Process
1. Angular CLI runs Webpack to build and bundle all JavaScript and CSS code.
2. In turn Webpack calls the TypeScript loaders which fetches all .ts
file in the Angular project and then transpiles them to JavaScript i.e to a .js
file, which browsers can understand.
This post says Angular has two compilers:
View Compiler
Module Compiler
Questions on builds
What is the sequence of calling the build process?
Angular CLI first calls Angular built-in compiler written in TypeScript => then calls the TypeScript Transpiler => then calls the Webpack to bundle and store in the dist/
directory.
How Angular runs
When build is completed, all our app's components, services, modules etc are transpiled to JavaScript .js
files which is used to run the Angular application in the browser.
Statements in Angular Docs
When you bootstrap with the AppComponent
class (in main.ts), Angular looks for a <app-root>
in the index.html
, finds it, instantiates an instance of AppComponent, and renders it inside the <app-root>
tag.
Angular creates, updates, and destroys components as the user moves through the application.
Questions on runs
Although main.ts
is used in the statement above for explaining the bootstrap process, Isn't Angular app is bootstrapped or started using JavaScript .js
files?
Isn't all the above statements are done runtime using JavaScript .js
files?
Does anyone know how all parts fit together in depth?
Angular CLI includes a first-party build system for Angular applications distributed as @angular-devkit/build-angular . This build system is responsible for creating a standalone single-page application (SPA) from user source files and third-party dependencies.
Angular follows component based architecture, in component-based architecture, a large application is broken (decoupled) into functional and logical components. These components are reusable hence can be used in any other part of the application.
(When I say Angular I mean Angular 2+ and will explicitly say angular-js if I am mentioning angular 1).
Angular, and probably more accurately angular-cli have merged together a number of trending tools in Javascript that are involved in the build process. It does lead to a little bit of confusion.
To further the confusion, the term compile
was often used in angular-js to refer to the process of taking the template's pseudo-html and turning it into DOM elements. That's part of what the compiler does but one of the smaller parts.
First of all, there is no need to use TypeScript, angular-cli, or Webpack to run Angular. To answer your question. We should look at a simple question: "What is Angular?"
This section may be controversial, we will see. At its core, the service that Angular provides, is a dependency injection mechanism which works across Javascript, HTML, and CSS. You write all the little bits and pieces individually and in each little piece you follow Angular's rules for referencing the other pieces. Angular then weaves that altogether somehow.
To be (slightly) more specific:
One possibly important thing to note is that Angular is not responsible for how Javascript files reference other Javascript files (e.g. the import
keyword). That is taken care of by Webpack.
Now that you know what Angular does we can talk about what the compiler does. I will avoid getting too technical mainly because I'm ignorant. However, in a dependency injection system you typically have to express your dependencies with some kind of metadata (e.g. how does a class say I can be injected
, My lifetime is blah
, or You can think of me as a Component type of instance
). In Java, Spring originally did this with XML files. Java later adopted annotations and they have become the preferred way to express metadata. C# uses attributes to express metadata.
Javascript does not have a great mechanism for exposing this metadata builtin. angular-js made an attempt and it wasn't bad but there were a lot of rules that couldn't be easily checked and were a little confusing. With Angular there are two supported ways of specifying the metadata. You can write pure Javascript and specify the metadata manually, somewhat similar to angular-js and just keep following the rules and writing extra boiler-platey code. Alternatively, you can switch to TypeScript which, as it just so happens, has decorators (those @
symbols) which are used to express metadata.
So here is where we can finally get to the compiler. The compiler's job is to take that metadata and create the system of working pieces that is your application. You focus on all the pieces and all of the metadata and the compiler builds one big interconnected application.
There are two ways the compiler can work, runtime and ahead-of-time. From here on I will assume you are using TypeScript:
index.html
you reference your main.js
which calls the bootstrap
method. That method is passed your top level module.The bootstrap method fires up the runtime compiler and gives it a reference to that top level module. The runtime compiler then starts to crawl that module, all services, components, etc. referenced by that module, and all of associated metadata, and builds up your application.
The advantage here is not just that you can save the CPU time required for the compilation itself, but it also allows you to reduce the size of your application.
Angular CLI First calls angular built in compiler written in Typescript => then calls the Typescript Transpiler => then calls the Webpack to bundle and store in the dist/ directory.
No. Angular CLI calls Webpack (Angular CLI's real service is configuring webpack. When you run ng build
it isn't much more than a proxy to starting Webpack). Webpack first calls the Typescript compiler, then the angular compiler (assuming AOT), all while bundling your code at the same time.
Although main.ts is used in Statement above for explaining bootstrap process, Isn't angular app is bootstrapped or started using Javascript .js files ?
I'm not entirely certain what you are asking here. main.ts
will be tranpiled down into Javascript. That Javascript will contain a call to bootstrap
which is the entry point to Angular. When bootstrap
is done you will have your full Angular application running.
This post says Angular has two compilers:
View Compiler
Module Compiler
To be honest I'm just going to claim ignorance here. I think at our level we can just think of it all as one big compiler.
Does anyone know how all parts fit together in depth ?
I hope the above satisfied this.
Sure. It does routing, view building, change detection and all kinds of other things. The compiler does actually generate Javascript for view building and change detection. I lied when I said it was just dependency injection. However, the dependency injection is at the core and enough to drive the rest of the answer.
It probably does a lot of parsing and lexing and definitely generates a lot of code as a result so you could call it a compiler for that reason.
On the other hand, it isn't really translating your code into merely a different representation. Instead it is taking a bunch of different pieces of code and weaving them into consumable pieces of a larger system. The bootstrap process then (after compiling, if necessary) takes those pieces and plugs them into the Angular core.
Let me start from the beginning.
In my application I directly run application from Webpack
.
To build and run the application we use webpack --progress and webpack-dev-server --inline command the has been written in package.json
as below
"scripts": {
"serve": "webpack-dev-server --inline ",
"build": "webpack --progress"
}
When we run webpack --progress
command it start's reading webpack.config.js
file where it find the entry point as below.
module.exports = {
devtool: 'source-map',
entry: './src/main.ts',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
loaders: [
{
test: /\.ts$/,
loaders: ['awesome-typescript-loader', 'angular2-template-loader'],
exclude: [/\.(spec|e2e)\.ts$/]
},
/* Embed files. */
{
test: /\.(html|css)$/,
loader: 'raw-loader',
exclude: /\.async\.(html|css)$/
},
/* Async loading. */
{
test: /\.async\.(html|css)$/,
loaders: ['file?name=[name].[hash].[ext]', 'extract']
},
]
},
resolve: {
extensions: ['.ts', '.js']
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
]
}
and then it read's all Typescript
file and compile's based on rules declared in the tsconfig.json
file and than convert's it to respective .js
files and it's map file.
If it runs without any compilation error it will create bundle.js
file with names as we declared in the Webpack
output section.
Now let me explain why we use loaders.
awesome-typescript-loader, angular2-template-loader We use these loader to compile the Typescript
file on the base declared in the tsconfig.json
file and angular2-template-loader searches for templateUrl
and styleUrls
declaration's inside of the Angular 2 Component metadata and replaces the paths with the corresponding require statement.
resolve: {
extensions: ['.ts', '.js']
}
We use above resolve section to tell Webpack
to convert Typescript
to JavaScript
file
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
]
Plugins section is used to inject third party framework or file.
In my code I am using this to inject index.html
of destination folder.
devtool: 'source-map',
Above line is used to see the Typescript
file in browser and debug it mostly used for developer code.
loader: 'raw-loader'
The above raw-loader
is used to load the .html
and .css
file and bundle them along with Typescript
files.
At the end when we run webpack-dev-server --inline it will create own server and boot-up the application as the path mentioned in web-pack.config.js
file where we mentioned destination folder and entry point.
In Angular
2 entry point of most application is main.ts
where we mention the initial bootstrap module for example(app.module) this module contain complete application information such as all directive,service,modules,components and routing implementation of whole application.
Note:
Many people's having doubt that why index.html
only boot-up the application, even though they have not mentioned any where.
The answer is when Webpack
serve command runs it create own serve and by default it load index.html
if you have not mention any default page.
I hope that given information help some people's.
How Angular builds ?
The Angular CLI
calls Webpack
, when Webpack
hits a .ts
file it passes it off to TypeScript
Compiler which has a output transformer which compiles Angular
templates
So build sequence is:
Angular CLI
=> Webpack
=> TypeScript
Compiler => TypeScript
Compiler calls the Angular
compiler in compile time.
How Angular runs ?
Angular
bootstraps and runs using Javascript
file.
Actually bootstrap process is runtime and happens before opening the browser. This takes us to our next question.
So If the bootstrap process happens with Javascript
file then why Angular
Docs uses main.ts
TypeScript file to explain bootstrap process ?
Angular
Docs just talk about the .ts
files since that's the source.
This is brief answer. Appreciate if anyone can answer in depth.
Credits goes to @Toxicable for answering my questions in chat.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With