angular 编译器 "compile" 是做什么的?
What does the angular compiler "compile"?
今天有人问我这个问题,但没能给出正确的答案。
Typescript 转译为 JS。然后是 tree shaking,"less"(可选)以及部署过程中的其他内容。但是这样的 (afaik) 与 "compiling" 没有任何关系。一切都被捆绑和高度优化,但实际上并没有编译,对吧?
甚至还有一个 "ahead of time"-编译器,它的工作确实非常出色。我想念什么?
Javascript本身还是被解释的吧?
您假设编译意味着获取源代码并生成机器代码、低级代码等。但编译实际上只是意味着获取一个源代码并将其转换为另一个。所以说取 Typescript 并生成 JavaScript 是一种 形式 的编译似乎是合理的。它与(例如)c# 编译成 IL 语言时所做的事情没有什么不同。
也就是说,我想用 Transpiling 来形容这个更好。我建议 Typescript 编译器 更好 描述为转译器。
区别很细微,可以将转译器视为一种编译器;但是(纯)编译语言(通常)将高级语言转换为低级语言(更接近机器代码),例如 C# 示例。转译器将高级语言转换为相似级别(抽象)语言(也是高级)。*
编译代码的结果通常不是您自己编写的语言。转译器的结果是另一种高级语言。理论上,您可以编写 IL(作为示例),但它实际上是为由编译器生成而设计的,并且没有工具或支持来执行此操作,您只能通过编译 C#/vb.net 来生成 IL。而 Javascript 本身就是一种可用(和使用)的编程语言。
*很多注意事项,因为这些词的定义及其用法非常模糊
在浏览器上获取您写入 运行 的代码涉及两件事:
1) 将 Typescript 转译为 JavaScript。这是一个已解决的问题。我认为他们只是使用 webpack。
2) 将 angular 抽象编译成 JavaScript。我指的是组件、管道、指令、模板等。这就是 angular 核心团队的工作。
如果您真的对第二位感兴趣,angular 编译器,watch compiler author Tobias Bosch explain the Angular Compiler at AngularConnect 2016。
我认为转译和编译之间存在一些混淆。这有点无关紧要,是个人品味的问题,它们都只是代码表示之间的转换。但是我个人使用的 definition 是 transpilation 是在相似抽象级别的两种不同语言之间(例如 typescript 到 javascript),而 compilation 需要降低抽象级别。我认为从模板、组件、管道、指令等到只是 javascript 是抽象阶梯上的一步,这就是它被称为编译器的原因。
你好像在问三个问题:
- 编译器和转译器有什么区别?
- Angular 和 TypeScript 是否实现了编译器或转译器?
- 有单独的Angular编译器吗?它编译了什么?
What is the difference between a compiler and transpiler?
@JörgWMittag 这个问题。
Do Angular and TypeScript implement compilers or transpilers?
TS 和 Angular 都实现了 真正的 编译器。它们遵循与生成汇编代码的 C/C++ 编译器相同的词法分析、解析、语义分析和代码生成阶段(除了优化)。您可以看到 class/folder 在 Angular and TS.
中都被命名为 "compiler"
angular 编译器与 TypeScript 编译器没有真正的关系。这些是非常不同的编译器。
Is there a separate Angular compiler? What does it compile?
Angular 有两个编译器:
- 查看编译器
- 模块编译器
视图编译器的工作是将您为组件模板指定的模板转换为组件的内部表示,该组件是一个视图工厂,然后用于实例化一个 视图实例.
视图编译器除了对模板进行转换之外,还以@HostBinding
、@ViewChild
等装饰器的形式编译各种元数据信息
假设您像这样定义一个组件及其模板:
@Component({
selector: 'a-comp',
template: '<span>A Component</span>'
})
class AComponent {}
使用此数据,编译器生成以下稍微简化的组件工厂:
function View_AComponent {
return jit_viewDef1(0,[
elementDef2(0,null,null,1,'span',...),
jit_textDef3(null,['My name is ',...])
]
它描述了组件视图的结构,在实例化组件时使用。第一个节点是元素定义,第二个节点是文本定义。可以看到每个节点在通过参数列表实例化的时候都获取到了自己需要的信息。解析所有必需的依赖项并在运行时提供它们是编译器的工作。
我强烈推荐阅读这些文章:
- Here is what you need to know about dynamic components in Angular
- Here is why you will not find components inside Angular
另请参阅
的答案
模块编译器的工作是创建一个模块工厂,其中基本上包含提供者的合并定义。
更多信息,请阅读:
Typescript transpires to JS. Then there is tree shaking, "less" (optional) and what else in the process of making a deployment. But nothing like that (afaik) has anything to do with "compiling". Everything gets bundled and heavily optimized, but it's not actually compiled, right?
编译表示将A语言编写的程序转换为B[语言编写的语义等价程序=106=] 这样根据语言 B 的规则评估编译程序(例如用 B 的解释器解释它)产生与根据语言规则 A 评估原始程序有相同的结果和相同的副作用(例如用 A[=106= 的解释器解释它]).
编译只是将程序从语言A翻译成语言B。这就是它的全部意思。 (另请注意,A 和 B 完全有可能是同一种语言。)
在某些情况下,我们对某些类型的编译器有更专门的名称,这取决于 A 和 B 是什么,以及什么编译器会:
- 如果A被认为是汇编语言而B被认为是机器语言,那么我们称它为汇编程序,
- 如果A被认为是机器语言而B被认为是汇编语言,那么我们称它为反汇编程序,
- 如果A被认为比B低级,那么我们称它为反编译器,
- 如果 A 和 B 是同一种语言,并且生成的程序在某些方面更快或更轻,那么我们称它为优化器、
- 如果A和B是相同的语言,并且生成的程序较小,那么我们称它为缩小器,
- 如果A和B是同一种语言,生成的程序可读性较差,那么我们称之为混淆器,
- 如果A和B被认为处于大致相同的抽象层次,那么我们称它为转译器,以及
- if A 和 B 被认为处于大致相同的抽象级别,并且生成的程序保留格式、注释和程序员的意图使得可以以与原始程序相同的方式维护生成的程序,然后我们将其称为重新设计工具。
另请注意,较旧的来源可能使用术语 "translation" 和 "translator" 而不是 "compilation" 和 "compiler"。比如C讲的是"translation units"。
您可能还会偶然发现 "language processor" 这个词。根据定义,这可能意味着编译器、解释器或编译器和解释器。
Javascript itself is still interpreted, right?
Java脚本是一种语言。语言是一组逻辑规则和限制。语言不会被解释或编译。语言 .
编译和解释是编译器或解释器的特征(duh!)。每种语言都可以用编译器实现,每种语言都可以用解释器实现。许多语言都有编译器和解释器。许多现代高性能执行引擎都至少有一个编译器和至少一个解释器。
这两个术语属于不同的抽象层。如果英语是一种输入语言,"interpreted-language" 将是一个类型错误。
另请注意,某些语言既没有解释器也没有编译器。有些语言根本没有实现。尽管如此,它们仍然是语言,您可以用它们编写程序。你就是不能 运行 他们。
此外,请注意,所有内容都在 某个点 进行解释:如果你想执行某事,你 必须 解释它。编译只是将代码从一种语言翻译成另一种语言。它没有 运行 它。 解读运行就这样了。 (有时,当解释器在硬件中实现时,我们称它为 "CPU",但它仍然是解释器。)
恰当的例子:当前存在的每一个主流Java脚本实现都有一个编译器。
V8 最初是一个纯编译器:它将 JavaScript 直接编译为适度优化的本机代码。后来,添加了第二个编译器。现在,有两种编译器:一种轻量级编译器,可生成适度优化的代码,但编译器本身速度非常快且使用的 RAM 很少。该编译器还将分析代码注入编译代码。第二个编译器是一个更重量级、更慢、更昂贵的编译器,然而,它产生更紧凑、更快的代码。它还使用第一个编译器注入的分析代码的结果来做出动态优化决策。此外,使用第二个编译器重新编译哪些代码的决定是基于该分析信息做出的。请注意,任何时候都不会涉及口译员。 V8 从不解释,它总是编译。它甚至不包含翻译。 (实际上,我相信现在确实如此,我正在描述前两次迭代。)
SpiderMonkey 将 JavaScript 编译为 SpiderMonkey 字节码,然后对其进行解释。解释器还对代码进行分析,然后最常执行的代码由编译器编译为本机机器码。因此,SpiderMonkey 包含 两个 编译器:一个从 JavaScript 到 SpiderMonkey 字节码,另一个从 SpiderMonkey 字节码到本地机器码。
几乎所有 Java脚本执行引擎(V8 除外)都遵循这种模型,即 AOT 编译器将 Java脚本编译为字节码,以及在解释和解释之间切换的混合模式引擎并编译该字节码。
您在评论中写道:
I really was thinking that machine code is somewhere involved.
"machine code" 是什么意思?
什么是一个人的机器语言是另一个人的中间语言,反之亦然?比如有CPU可以原生执行JVM字节码,在这样的CPU上,JVM字节码是原生机器码。并且有 x86 机器代码的解释器,当你 运行 那些 x86 机器代码 是 解释字节码时。
有一个叫JPC的x86解释器是用Java写的。如果我 运行 JPC 上的 x86 机器码 运行ning 在本机 JVM CPU 上……哪个是字节码,哪个是本机代码?如果我将 x86 机器代码编译为 JavaScript(是的,有可以做到这一点的工具)并在我的 phone 上的浏览器中 运行 它(它有一个 ARM CPU),哪个是字节码,哪个是本机机器码?如果我正在编译的程序是一个 SPARC 模拟器,我用它来 运行 SPARC 代码怎么办?
请注意,每种 语言都归纳出一个抽象机器,并且是该机器的机器语言。因此,每种语言(包括非常高级的语言)都是本机机器代码。此外,您可以为每种语言编写解释器。因此,每种语言(包括 x86 机器代码)都不是本地语言。
Angular 编译器
从 Angular 4 到 5 最重要的变化之一是编译器被重写得更快、更彻底。过去,Angular 应用程序使用我们所说的即时 (JIT) 编译,其中应用程序在 运行 时间在 运行 之前在浏览器中编译。 Angular 5 中的编译器更新推进了向 AOT 的迁移,这使得应用程序 运行 更快,因为它在 运行 应用程序时执行更少的编译。自 1.5 版本的 Angular CLI 以来,任何生产版本都默认启用 AOT。
假设我们要构建一个用于部署的应用程序和运行以下命令:
ng build --prod
发生了一些事情:生产版本、缩小、捆绑资产、文件名散列、tree shaking、AOT ...(我们可以 enable/disable 使用标志,例如 aot=false)。简而言之,prod 标志通过使用 ngc(Angular 编译器)进行 AOT 编译来创建应用程序的优化包,从而为浏览器创建优化代码(是的,它预编译模板)。
TypeScript 编译器
TypeScript 编译器,tsc,负责编译 TypeScript 文件。编译器负责实现 TypeScript 特性,例如静态类型,结果是纯粹的 JavaScript,其中 TypeScript 关键字和表达式已被删除。
TypeScript 编译器有两个主要特性:它是一个转译器和一个类型检查器。编译器将 TypeScript 转换为 JavaScript。它对您的源代码进行以下转换:
- 删除所有类型注释。
- 为旧版本 JavaScript 编译新的 JavaScript 功能。
- 编译非标准的 TypeScript 功能 JavaScript。
调用它时,编译器会搜索 tsconfig.json 中加载的配置(可以找到所有编译器选项的详细列表以及默认值 here)。
在大多数方面,TypeScript 编译器的工作方式与任何编译器一样。但是有一个区别可能会引起粗心:默认情况下,编译器即使在遇到错误时也会继续发出 JavaScript 代码。幸运的是,可以通过在 tsconfig.json 文件中将 noEmitOnError
配置设置设置为 true 来禁用此行为。
注意:tsc和ngc有不同的用途,不是选择一个在另一个之上。 .
此答案是根据以下书籍的内容精心制作的
Cloe, M. (2018)。 "Angular 5 Projects: Learn to Build Single Page Web Applications Using 70+ Projects".
Dewey, B.、Grossnicklaus, K.、Japikse, P.(2017 年)。 "Building Web Applications with Visual Studio 2017: Using .NET Core and Modern JavaScript Frameworks".
Freeman, A. (2019)。 "Essential TypeScript: From Beginner to Pro".
Ghiya, P. (2018)。 "TypeScript Microservices".
Iskandar, A., Chivukulu, S. (2019)。 "Web Development with Angular and Bootstrap - Third Edition".
Hennessy, K., Arora, C. (2018)。 "Angular 6 by Example".
Jansen, R., Wolf, I., Vane, V. (2016)。 "TypeScript: Modern JavaScript Development".
Mohammed, Z. (2019)。 "Angular Projects".
Seshadri, S. (2018)。 "Angular: Up and Running".
威尔肯,J.(2018 年)。 "Angular in Action".
今天有人问我这个问题,但没能给出正确的答案。
Typescript 转译为 JS。然后是 tree shaking,"less"(可选)以及部署过程中的其他内容。但是这样的 (afaik) 与 "compiling" 没有任何关系。一切都被捆绑和高度优化,但实际上并没有编译,对吧?
甚至还有一个 "ahead of time"-编译器,它的工作确实非常出色。我想念什么?
Javascript本身还是被解释的吧?
您假设编译意味着获取源代码并生成机器代码、低级代码等。但编译实际上只是意味着获取一个源代码并将其转换为另一个。所以说取 Typescript 并生成 JavaScript 是一种 形式 的编译似乎是合理的。它与(例如)c# 编译成 IL 语言时所做的事情没有什么不同。
也就是说,我想用 Transpiling 来形容这个更好。我建议 Typescript 编译器 更好 描述为转译器。
区别很细微,可以将转译器视为一种编译器;但是(纯)编译语言(通常)将高级语言转换为低级语言(更接近机器代码),例如 C# 示例。转译器将高级语言转换为相似级别(抽象)语言(也是高级)。*
编译代码的结果通常不是您自己编写的语言。转译器的结果是另一种高级语言。理论上,您可以编写 IL(作为示例),但它实际上是为由编译器生成而设计的,并且没有工具或支持来执行此操作,您只能通过编译 C#/vb.net 来生成 IL。而 Javascript 本身就是一种可用(和使用)的编程语言。
*很多注意事项,因为这些词的定义及其用法非常模糊
在浏览器上获取您写入 运行 的代码涉及两件事:
1) 将 Typescript 转译为 JavaScript。这是一个已解决的问题。我认为他们只是使用 webpack。
2) 将 angular 抽象编译成 JavaScript。我指的是组件、管道、指令、模板等。这就是 angular 核心团队的工作。
如果您真的对第二位感兴趣,angular 编译器,watch compiler author Tobias Bosch explain the Angular Compiler at AngularConnect 2016。
我认为转译和编译之间存在一些混淆。这有点无关紧要,是个人品味的问题,它们都只是代码表示之间的转换。但是我个人使用的 definition 是 transpilation 是在相似抽象级别的两种不同语言之间(例如 typescript 到 javascript),而 compilation 需要降低抽象级别。我认为从模板、组件、管道、指令等到只是 javascript 是抽象阶梯上的一步,这就是它被称为编译器的原因。
你好像在问三个问题:
- 编译器和转译器有什么区别?
- Angular 和 TypeScript 是否实现了编译器或转译器?
- 有单独的Angular编译器吗?它编译了什么?
What is the difference between a compiler and transpiler?
@JörgWMittag
Do Angular and TypeScript implement compilers or transpilers?
TS 和 Angular 都实现了 真正的 编译器。它们遵循与生成汇编代码的 C/C++ 编译器相同的词法分析、解析、语义分析和代码生成阶段(除了优化)。您可以看到 class/folder 在 Angular and TS.
中都被命名为 "compiler"angular 编译器与 TypeScript 编译器没有真正的关系。这些是非常不同的编译器。
Is there a separate Angular compiler? What does it compile?
Angular 有两个编译器:
- 查看编译器
- 模块编译器
视图编译器的工作是将您为组件模板指定的模板转换为组件的内部表示,该组件是一个视图工厂,然后用于实例化一个 视图实例.
视图编译器除了对模板进行转换之外,还以@HostBinding
、@ViewChild
等装饰器的形式编译各种元数据信息
假设您像这样定义一个组件及其模板:
@Component({
selector: 'a-comp',
template: '<span>A Component</span>'
})
class AComponent {}
使用此数据,编译器生成以下稍微简化的组件工厂:
function View_AComponent {
return jit_viewDef1(0,[
elementDef2(0,null,null,1,'span',...),
jit_textDef3(null,['My name is ',...])
]
它描述了组件视图的结构,在实例化组件时使用。第一个节点是元素定义,第二个节点是文本定义。可以看到每个节点在通过参数列表实例化的时候都获取到了自己需要的信息。解析所有必需的依赖项并在运行时提供它们是编译器的工作。
我强烈推荐阅读这些文章:
- Here is what you need to know about dynamic components in Angular
- Here is why you will not find components inside Angular
另请参阅
模块编译器的工作是创建一个模块工厂,其中基本上包含提供者的合并定义。
更多信息,请阅读:
Typescript transpires to JS. Then there is tree shaking, "less" (optional) and what else in the process of making a deployment. But nothing like that (afaik) has anything to do with "compiling". Everything gets bundled and heavily optimized, but it's not actually compiled, right?
编译表示将A语言编写的程序转换为B[语言编写的语义等价程序=106=] 这样根据语言 B 的规则评估编译程序(例如用 B 的解释器解释它)产生与根据语言规则 A 评估原始程序有相同的结果和相同的副作用(例如用 A[=106= 的解释器解释它]).
编译只是将程序从语言A翻译成语言B。这就是它的全部意思。 (另请注意,A 和 B 完全有可能是同一种语言。)
在某些情况下,我们对某些类型的编译器有更专门的名称,这取决于 A 和 B 是什么,以及什么编译器会:
- 如果A被认为是汇编语言而B被认为是机器语言,那么我们称它为汇编程序,
- 如果A被认为是机器语言而B被认为是汇编语言,那么我们称它为反汇编程序,
- 如果A被认为比B低级,那么我们称它为反编译器,
- 如果 A 和 B 是同一种语言,并且生成的程序在某些方面更快或更轻,那么我们称它为优化器、
- 如果A和B是相同的语言,并且生成的程序较小,那么我们称它为缩小器,
- 如果A和B是同一种语言,生成的程序可读性较差,那么我们称之为混淆器,
- 如果A和B被认为处于大致相同的抽象层次,那么我们称它为转译器,以及
- if A 和 B 被认为处于大致相同的抽象级别,并且生成的程序保留格式、注释和程序员的意图使得可以以与原始程序相同的方式维护生成的程序,然后我们将其称为重新设计工具。
另请注意,较旧的来源可能使用术语 "translation" 和 "translator" 而不是 "compilation" 和 "compiler"。比如C讲的是"translation units"。
您可能还会偶然发现 "language processor" 这个词。根据定义,这可能意味着编译器、解释器或编译器和解释器。
Javascript itself is still interpreted, right?
Java脚本是一种语言。语言是一组逻辑规则和限制。语言不会被解释或编译。语言 .
编译和解释是编译器或解释器的特征(duh!)。每种语言都可以用编译器实现,每种语言都可以用解释器实现。许多语言都有编译器和解释器。许多现代高性能执行引擎都至少有一个编译器和至少一个解释器。
这两个术语属于不同的抽象层。如果英语是一种输入语言,"interpreted-language" 将是一个类型错误。
另请注意,某些语言既没有解释器也没有编译器。有些语言根本没有实现。尽管如此,它们仍然是语言,您可以用它们编写程序。你就是不能 运行 他们。
此外,请注意,所有内容都在 某个点 进行解释:如果你想执行某事,你 必须 解释它。编译只是将代码从一种语言翻译成另一种语言。它没有 运行 它。 解读运行就这样了。 (有时,当解释器在硬件中实现时,我们称它为 "CPU",但它仍然是解释器。)
恰当的例子:当前存在的每一个主流Java脚本实现都有一个编译器。
V8 最初是一个纯编译器:它将 JavaScript 直接编译为适度优化的本机代码。后来,添加了第二个编译器。现在,有两种编译器:一种轻量级编译器,可生成适度优化的代码,但编译器本身速度非常快且使用的 RAM 很少。该编译器还将分析代码注入编译代码。第二个编译器是一个更重量级、更慢、更昂贵的编译器,然而,它产生更紧凑、更快的代码。它还使用第一个编译器注入的分析代码的结果来做出动态优化决策。此外,使用第二个编译器重新编译哪些代码的决定是基于该分析信息做出的。请注意,任何时候都不会涉及口译员。 V8 从不解释,它总是编译。它甚至不包含翻译。 (实际上,我相信现在确实如此,我正在描述前两次迭代。)
SpiderMonkey 将 JavaScript 编译为 SpiderMonkey 字节码,然后对其进行解释。解释器还对代码进行分析,然后最常执行的代码由编译器编译为本机机器码。因此,SpiderMonkey 包含 两个 编译器:一个从 JavaScript 到 SpiderMonkey 字节码,另一个从 SpiderMonkey 字节码到本地机器码。
几乎所有 Java脚本执行引擎(V8 除外)都遵循这种模型,即 AOT 编译器将 Java脚本编译为字节码,以及在解释和解释之间切换的混合模式引擎并编译该字节码。
您在评论中写道:
I really was thinking that machine code is somewhere involved.
"machine code" 是什么意思?
什么是一个人的机器语言是另一个人的中间语言,反之亦然?比如有CPU可以原生执行JVM字节码,在这样的CPU上,JVM字节码是原生机器码。并且有 x86 机器代码的解释器,当你 运行 那些 x86 机器代码 是 解释字节码时。
有一个叫JPC的x86解释器是用Java写的。如果我 运行 JPC 上的 x86 机器码 运行ning 在本机 JVM CPU 上……哪个是字节码,哪个是本机代码?如果我将 x86 机器代码编译为 JavaScript(是的,有可以做到这一点的工具)并在我的 phone 上的浏览器中 运行 它(它有一个 ARM CPU),哪个是字节码,哪个是本机机器码?如果我正在编译的程序是一个 SPARC 模拟器,我用它来 运行 SPARC 代码怎么办?
请注意,每种 语言都归纳出一个抽象机器,并且是该机器的机器语言。因此,每种语言(包括非常高级的语言)都是本机机器代码。此外,您可以为每种语言编写解释器。因此,每种语言(包括 x86 机器代码)都不是本地语言。
Angular 编译器
从 Angular 4 到 5 最重要的变化之一是编译器被重写得更快、更彻底。过去,Angular 应用程序使用我们所说的即时 (JIT) 编译,其中应用程序在 运行 时间在 运行 之前在浏览器中编译。 Angular 5 中的编译器更新推进了向 AOT 的迁移,这使得应用程序 运行 更快,因为它在 运行 应用程序时执行更少的编译。自 1.5 版本的 Angular CLI 以来,任何生产版本都默认启用 AOT。
假设我们要构建一个用于部署的应用程序和运行以下命令:
ng build --prod
发生了一些事情:生产版本、缩小、捆绑资产、文件名散列、tree shaking、AOT ...(我们可以 enable/disable 使用标志,例如 aot=false)。简而言之,prod 标志通过使用 ngc(Angular 编译器)进行 AOT 编译来创建应用程序的优化包,从而为浏览器创建优化代码(是的,它预编译模板)。
TypeScript 编译器
TypeScript 编译器,tsc,负责编译 TypeScript 文件。编译器负责实现 TypeScript 特性,例如静态类型,结果是纯粹的 JavaScript,其中 TypeScript 关键字和表达式已被删除。
TypeScript 编译器有两个主要特性:它是一个转译器和一个类型检查器。编译器将 TypeScript 转换为 JavaScript。它对您的源代码进行以下转换:
- 删除所有类型注释。
- 为旧版本 JavaScript 编译新的 JavaScript 功能。
- 编译非标准的 TypeScript 功能 JavaScript。
调用它时,编译器会搜索 tsconfig.json 中加载的配置(可以找到所有编译器选项的详细列表以及默认值 here)。
在大多数方面,TypeScript 编译器的工作方式与任何编译器一样。但是有一个区别可能会引起粗心:默认情况下,编译器即使在遇到错误时也会继续发出 JavaScript 代码。幸运的是,可以通过在 tsconfig.json 文件中将 noEmitOnError
配置设置设置为 true 来禁用此行为。
注意:tsc和ngc有不同的用途,不是选择一个在另一个之上。
此答案是根据以下书籍的内容精心制作的
Cloe, M. (2018)。 "Angular 5 Projects: Learn to Build Single Page Web Applications Using 70+ Projects".
Dewey, B.、Grossnicklaus, K.、Japikse, P.(2017 年)。 "Building Web Applications with Visual Studio 2017: Using .NET Core and Modern JavaScript Frameworks".
Freeman, A. (2019)。 "Essential TypeScript: From Beginner to Pro".
Ghiya, P. (2018)。 "TypeScript Microservices".
Iskandar, A., Chivukulu, S. (2019)。 "Web Development with Angular and Bootstrap - Third Edition".
Hennessy, K., Arora, C. (2018)。 "Angular 6 by Example".
Jansen, R., Wolf, I., Vane, V. (2016)。 "TypeScript: Modern JavaScript Development".
Mohammed, Z. (2019)。 "Angular Projects".
Seshadri, S. (2018)。 "Angular: Up and Running".
威尔肯,J.(2018 年)。 "Angular in Action".