Angular 如何构建和运行 [英] How Angular builds and runs

查看:39
本文介绍了Angular 如何构建和运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

只是想了解 Angular 如何在幕后构建和运行?

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.

Angular 如何构建

在使用 TypeScript 对我们的 Angular 应用程序进行编码后,我们使用 Angular CLI 命令来构建应用程序.

After coding our Angular apps using TypeScript, we use the Angular CLI command to build the app.

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

ng build command compiles the application into an output directory and the build artifacts will be stored in the dist/ directory.

内部流程

1. Angular CLI 运行 Webpack 来构建和捆绑所有 JavaScript 和 CSS 代码.

1. Angular CLI runs Webpack to build and bundle all JavaScript and CSS code.

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

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.

这篇帖子说 Angular 有两个编译器:

This post says Angular has two compilers:

  • 查看编译器

  • View Compiler

模块编译器

关于构建的问题

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

What is the sequence of calling the build process?

Angular CLI 首先调用用 TypeScript 编写的 Angular 内置编译器 => 然后调用 TypeScript Transpiler => 然后调用 Webpack 打包并存储在 dist/ 目录中.

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.

Angular 如何运行

构建完成后,我们应用程序的所有组件、服务、模块等都将转换为 JavaScript .js 文件,用于在浏览器中运行 Angular 应用程序.

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.

Angular 文档

  1. 当您使用 AppComponent 类(在 main.ts 中)进行引导时,Angular 会在 index 中查找 .html,找到它,实例化 AppComponent 的一个实例,并将它呈现在 标签内.

  1. 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 在用户在应用程序中移动时创建、更新和销毁组件.

Angular creates, updates, and destroys components as the user moves through the application.

跑步问题

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

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?

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

Isn't all the above statements are done runtime using JavaScript .js files?

有谁知道所有部分是如何深度组合在一起的?

Does anyone know how all parts fit together in depth?

推荐答案

(当我说 Angular 时,我指的是 Angular 2+,如果我提到 Angular 1,我会明确说 angular-js).

Angular,或许更准确地说,angular-cli 已经将一些参与构建过程的 Javascript 趋势工具合并在一起.这确实会导致一些混乱.

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.

为了进一步混淆,术语 compile 在 angular-js 中经常使用,指的是将模板的伪 html 转换为 DOM 元素的过程.这是编译器所做工作的一部分,只是较小的部分之一.

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.

首先,不需要使用 TypeScript、angular-cli 或 Webpack 来运行 Angular.回答你的问题.我们应该看一个简单的问题:什么是 Angular?"

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 提供的服务的核心是一种依赖注入机制,它可以跨 Javascript、HTML 和 CSS 工作.您单独编写所有的小部分,并在每个小部分中遵循 Angular 的规则用于参考其他作品.然后 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.

(稍微)更具体:

  • 模板允许将 HTML 连接到 Javascript 组件中.这允许用户对 DOM 本身的输入(例如单击按钮)输入到 Javascript 组件中,还允许 Javascript 组件中的变量控制 DOM 中的结构和值.
  • Javascript 类(包括 Javascript 组件)需要能够访问它们所依赖的其他 Javascript 类的实例(例如经典依赖注入).BookListComponent 需要一个 BookListService 的实例,它可能需要一个 BookListPolicy 的实例或类似的东西.这些类中的每一个都有不同的生命周期(例如,服务通常是单例,组件通常不是单例),而 Angular 必须管理所有这些生命周期、组件的创建以及依赖项的连接.
  • CSS 规则需要以这样的方式加载,即它们仅适用于 DOM 的一个子集(组件的样式是该组件的本地样式).

一个可能需要注意的重要事项是 Angular 不负责 Javascript 文件如何引用其他 Javascript 文件(例如 import 关键字).这由 Webpack 负责.

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.

既然您知道了 Angular 的作用,我们就可以谈谈编译器的作用了.我会避免太技术化,主要是因为我无知.但是,在依赖注入系统中,您通常必须使用某种元数据来表达您的依赖关系(例如,类如何说I can be injectionMy life is blah、或者你可以把我看作一个组件类型的实例).在 Java 中,Spring 最初是用 XML 文件完成的.Java 后来采用了注解,它们已成为表达元数据的首选方式.C# 使用属性来表达元数据.

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 没有很好的机制来公开这个内置的元数据.angular-js 做了一次尝试,还不错,但是有很多规则不容易检查,而且有点混乱.Angular 支持两种指定元数据的方式.您可以编写纯 Javascript 并手动指定元数据,有点类似于 angular-js,只需遵循规则并编写额外的样板代码即可.或者,您可以切换到 TypeScript,它恰好具有用于表达元数据的装饰器(那些 @ 符号).

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.

编译器有两种工作方式,运行时和提前.从这里开始,我将假设您使用的是 TypeScript:

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

  • 运行时:当打字稿编译器运行时,它会获取所有装饰器信息,并将其放入附加到装饰类、方法和字段的 Javascript 代码中.在您的 index.html 中,您引用了调用 bootstrap 方法的 main.js.该方法传递给您的顶级模块.
  • 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.

bootstrap 方法启动运行时编译器并给它一个对顶级模块的引用.然后,运行时编译器开始抓取该模块、该模块引用的所有服务、组件等以及所有关联的元数据,并构建您的应用程序.

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: Angular 提供了一种机制,可以在构建时完成大部分工作,而不是在运行时完成所有工作.这几乎总是使用一个webpack插件来完成(这一定是最流行的插件之一鲜为人知的 npm 包).它在打字稿编译运行后运行,因此它看到的输入与运行时编译器基本相同.AOT 编译器像运行时编译器一样构建您的应用程序,然后将其保存回 Javascript.
  • 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.

这里的优势不仅在于您可以节省编译本身所需的 CPU 时间,而且还允许您减小应用程序的大小.

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 首先调用 angular 内置编译器编写的Typescript => 然后调用 Typescript Transpiler => 然后调用Webpack 打包并存储在 dist/目录中.

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.

没有.Angular CLI 调用 Webpack(Angular CLI 的真正服务是配置 webpack.当您运行 ng build 时,它只不过是启动 Webpack 的代理).Webpack 首先调用 Typescript 编译器,然后调用 angular 编译器(假设 AOT),同时打包您的代码.

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.

虽然上面的 Statement 中使用了 main.ts 来解释 bootstrap过程,不是使用 Javascript 引导或启动 Angular 应用程序.js 文件?

Although main.ts is used in Statement above for explaining bootstrap process, Isn't angular app is bootstrapped or started using Javascript .js files ?

我不完全确定你在这里问的是什么.main.ts 将被编译成 Javascript.该 Javascript 将包含对 bootstrap 的调用,这是 Angular 的入口点.当 bootstrap 完成后,您将运行完整的 Angular 应用程序.

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.

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

This post says Angular has two compilers:

查看编译器

模块编译器

老实说,我只是想在这里声明无知.我认为在我们的层面上,我们可以将其视为一个大型编译器.

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.

当然.它执行路由、查看构建、更改检测和各种其他事情.编译器确实会生成用于视图构建和更改检测的 Javascript.当我说这只是依赖注入时,我撒了谎.然而,依赖注入是核心,足以驱动其余的答案.

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.

另一方面,它并没有真正将您的代码转换为一种不同的表示形式.相反,它需要一堆不同的代码片段并将它们编织成更大系统的可消耗片段.然后引导程序(在编译之后,如果需要)获取这些部分并将它们插入到 Angular 核心中.

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.

这篇关于Angular 如何构建和运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆