(When I say Angular I mean Angular 2+ and will explicitly say angular-js if I am mentioning angular 1).
序曲:令人困惑
Angular,可能更准确地说,Angular cli已经将构建过程中涉及的许多Javascript趋势工具合并在一起.这确实会引起一些困惑.
为了进一步加深混淆,angular js中经常使用术语compile
来表示获取模板的伪html并将其转换为DOM元素的过程.这是编译器工作的一部分,只是其中一个较小的部分.
首先,运行angular不需要使用TypeScript、angular cli或Webpack.回答你的问题.我们应该看一个简单的问题:"什么是Angular ?"
角:它是做什么的?
这一部分可能会引起争议,我们将拭目以待.At its core, the service that Angular provides, is a dependency injection mechanism which works across Javascript, HTML, and CSS..你把所有的小片段单独写下来,在每个小片段中,你都遵循Angular的规则来引用其他片段.然后以某种方式编织起来.
更具体地说:
- 模板允许将HTML连接到Javascript组件中.这允许用户对DOM本身的输入(例如单击按钮)输入到Javascript组件中,还允许Javascript组件中的变量控制DOM中的 struct 和值.
- Javascript类(包括Javascript组件)需要能够访问它们所依赖的其他Javascript类的实例(例如,classic 依赖注入).BookListComponent需要BookListService的实例,而BookListService可能需要BookListPolicy或类似的实例.这些类中的每一个都有不同的生存期(例如,服务通常是单例的,组件通常不是单例的),Angular必须管理所有这些生存期、组件的创建以及依赖项的连接.
- CSS规则需要以这样的方式加载,即它们只应用于DOM的一个子集(组件的样式是该组件的本地样式).
需要注意的一件可能很重要的事情是,Angular不负责Javascript文件如何引用其他Javascript文件(例如import
关键字).这是由Webpack负责的.
编译器做什么?
现在你知道了Angular是做什么的,我们可以讨论一下编译器是做什么的.我会避免太过技术化,主要是因为我无知.然而,在一个类中,你通常有一些依赖关系,比如说,You can think of me as a Component type of instance
是如何表达你的依赖关系的.在Java中,Spring最初是通过XML文件实现的.Java后来采用了注释,它们已成为表示元数据的首选方式.C#使用属性来表示元数据.
Javascript没有很好的机制来公开这种内置的元数据.angular js做了一次try ,结果不错,但有很多规则不容易判断,而且有点混乱.对于Angular,有两种受支持的指定元数据的方法.您可以编写纯Javascript并手动指定元数据,这有点类似于angular js,只需遵循规则并编写额外的代码即可.或者,您可以切换到TypeScript,正如它所发生的那样,它有用于表示元数据的装饰符(这@
个符号).
这就是我们最终可以使用编译器的地方.编译器的工作是获取元数据并创建作为应用程序的工件系统.你关注所有的片段和所有的元数据,编译器会构建一个大型的互联应用程序.
编译器是如何做到的?
编译器有两种工作方式,运行时和提前.从这里开始,我假设您正在使用TypeScript:
- Runtime:当typescript编译器运行时,它会获取所有decorator 信息,并将其放入附加到装饰类、方法和字段的Javascript代码中.在
index.html
中,你引用了main.js
,它调用bootstrap
方法.该方法将传递给顶级模块.
bootstrap方法启动运行时编译器,并为其提供对顶层模块的引用.然后,运行时编译器开始对该模块、该模块引用的所有服务、组件等以及所有相关元数据进行爬网,并构建应用程序.
- AOT: Angular并没有在运行时完成所有工作,而是提供了一种在构建时完成大部分工作的机制.这几乎总是使用a webpack plugin来完成的(这必须是最流行但最鲜为人知的npm包之一).它在typescript编译运行之后运行,因此它看到的输入基本上与运行时编译器相同.AOT编译器会像运行时编译器一样构建应用程序,但会将其保存回Javascript.
这里的优点不仅是可以节省编译本身所需的CPU时间,还可以减少应用程序的大小.
具体答案
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),同时绑定代码.
虽然是主要的.ts在上面的语句中用于解释 bootstrap
我不完全确定你在问什么.main.ts
将被转换成Javascript.该Javascript将包含对bootstrap
的调用,bootstrap
是Angular的入口点.完成bootstrap
后,您将运行完整的Angular 应用程序.
这篇文章说Angular有两个编译器:
视图编译器
模块编译器
老实说,我只想在这里说我无知.我认为在我们的水平上,我们可以把它看作一个大的编译器.
有人知道所有部件是如何在深度上结合在一起的吗?
我希望以上内容能满足这一点.
不要@Me:Angular做的不仅仅是依赖注入
当然它可以进行布线、视图构建、变更检测和各种其他工作.编译器实际上会生成用于视图构建和更改检测的Javascript.我撒谎说那只是依赖注射.然而,依赖注入是核心,足以驱动其余答案.
我们应该称之为编译器吗?
它可能会进行大量的解析和词法分析,并最终生成大量代码,因此您可以将其称为编译器.
另一方面,它并不是真正地将代码转换为一种不同的表示形式.相反,它需要一堆不同的代码,并将它们编织成一个更大系统的可消费部分.然后, bootstrap 过程(在编译之后,如果必要的话)将这些片段插入到Angular core中.