角度是如何建立和运行的

想知道 Angular 是如何在幕后构建和运行的吗?

下面是我到目前为止所了解的。想知道我是否遗漏了什么。

角度是如何形成的

在使用 TypeScript 编写了我们的 Angular 应用程序之后,我们使用 Angular CLI 命令来构建这个应用程序。

ng build命令将应用程序编译到一个输出目录中,构建构件将存储在 dist/目录中。

内部程序

角度 CLI 运行 Webpack 来构建和捆绑所有的 JavaScript 和 CSS 代码。

2.反过来,Webpack 调用 TypeScript 加载器,该加载器获取 Angular 项目中的所有 .ts文件,然后将它们转换为 JavaScript 即 .js文件,浏览器可以理解这个文件。

这篇文章说 Angular 有两个编译器:

  • 查看编译器

  • 模组编译器

关于构建的问题

调用构建过程的顺序是什么?

Angular CLI 首先调用用 TypeScript = > 编写的 Angular 内置编译器,然后调用 TypeScript Transiler = > ,然后调用 Webpack 捆绑并存储在 dist/目录中。

角度是如何运行的

当构建完成后,我们所有的应用程序的组件,服务,模块等被传输到 JavaScript .js文件,这是用来运行在浏览器中的角度应用程序。

Angular Docs的发言

  1. 当您使用 AppComponent类(在 main.ts 中)引导时,Angular 在 index.html中查找 <app-root>,找到它,实例化 AppComponent 的一个实例,并在 <app-root>标记中呈现它。

  2. 当用户在应用程序中移动时,角度创建、更新和销毁组件。

关于跑步的问题

虽然在上面的语句中使用了 main.ts来解释引导过程,但是 Angular 应用程序不是使用 JavaScript.js文件引导或启动的吗?

上面的所有语句不都是使用 JavaScript.js文件在运行时完成的吗?

有人知道如何将所有部分深入地结合在一起吗?

55283 次浏览

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.

(When I say Angular I mean Angular 2+ and will explicitly say angular-js if I am mentioning angular 1).

Prelude: It is confusing

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?"

Angular: What does it do?

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:

  • Templates allow HTML to be wired into the Javascript component. This allows user input on the DOM itself (e.g. clicking a button) to feed into the Javascript component and also allows variables in the Javascript component to control the structure and values in the DOM.
  • Javascript classes (including Javascript components) need to be able to access instances of other Javascript classes they depend on (e.g. classical dependency injection). A BookListComponent needs an instance of a BookListService which might need an instance of a BookListPolicy or something like that. Each of these classes has different lifetimes (e.g. services are usually singletons, components are usually not singletons) and Angular has to manage all those lifetimes, the creation of the components, and the wiring of the dependencies.
  • CSS rules needed to be loaded in such a way that they only apply to a subset of the DOM (a component's style is local to that component).

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.

What does the compiler do?

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.

How does the compiler do it?

There are two ways the compiler can work, runtime and ahead-of-time. From here on I will assume you are using TypeScript:

  • Runtime: When the typescript compiler runs it takes all the decorator information and shoves it into the Javascript code attached to the decorated classes, methods, and fields. In your 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.

  • AOT: Rather than do all the work at runtime Angular has provided a mechanism for doing most the work at build time. This is almost always done using a webpack plugin (this must be one of the most popular yet least known npm packages). It runs after the typescript compilation has run so it sees essentially the same input as the runtime compiler. The AOT compiler builds up your application just like the runtime compiler but then saves it back out into Javascript.

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.

Specific Answers

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.

Don't @ Me: Angular does more than dependency injection

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.

Should we call it a compiler?

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.

So If the bootstrap process happens with Javascript file then why Angular Docs uses main.ts TypeScript file to explain bootstrap process ?

This is part of the transformed .js version of main.ts emitted by ng build which is not yet uglified and minified, How do you expect for a beginner to comprehend this code? doesn't it look way much complicated?

Object(__WEBPACK_IMPORTED_MODULE_1__angular_platform_browser_dynamic__["a" /* platformBrowserDynamic */])().bootstrapModule(__WEBPACK_IMPORTED_MODULE_2__app_app_module__["a" /* AppModule */])
.catch(function (err) { return console.log(err); });

and with ng build --prod --build-optimizer which uglifies and minifies your code in order to optimize it, generated bundles are compact and are in bit-unreadable format.

webpackJsonp([1],{0:function(t,e,n){t.exports=n("cDNt")},"1j/l":function(t,e,n){"use strict";n.d(e,"a",function(){return r});var r=Array.isArray||function(t){return t&&"number"==typeof t.length}},"2kLc

whereas main.ts file is human readable and lucid, that's why the angular.io uses main.ts to explain the bootstrap process of angular application.Angular: Why TypeScript? apart from this if you had been an author of such a great framework what approach you would have used in order to make your framework popular and user-friendly? wouldn't you go for clear and concise explanation rather than a complicated one? I agree angular.io documentation lacks in-depth explanation and it is not pretty great but as far I have seen they are striving hard to make it better.

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.

Might be late for this answer, but there have been a really good talk recently about this topic, which starts from a beginner viewpoint and goes in depth. Instead of trying to summarize or point out misinformation in this thread with my words, I'll just link the video by Kara Erickson: How Angular works.

She is the tech lead on the Angular framework, and does a really good presentation on:

  • what are the main parts of the Angular framework
  • how does the compiler work, what does it produce
  • what is a "Component definition"
  • What is an application bootstrap, how does it work

Angular 9+ uses AOT (Ahead of Time Compilation) which means it takes all the bits scattered in various files i.e. component (.ts + .html + .css), modules (.ts) and construct browser understandable JavaScript which at runtime is downloaded and executed by the browser.

Prior to Angular 9 it was JIT (Just in time Compilation) where the code was compiled as it was required by the browser.

For details see: Angular AOT Documentaiton