angular度编译器“编译”是什么?

今天我被问到,无法给出正确的答案。

Typescript转换到JS。 那么就有树在摇晃,“less”(可选)以及在部署过程中还有什么。 但是没有什么比这个(afaik)和“编译”有什么关系。 一切都得到了捆绑和大量优化,但它并没有真正编译,对不对?

甚至提前编译器,这确实是一个明显的工作。 我错过了什么?

JavaScript本身仍然被解释,对吧?

你假设编译手段是采取源代码和生成机器码,低级代码等。但编译实际上意味着采取一个源代码并将其转换为另一个源代码。 因此,认为使用Typescript和生成JavaScript是一种编译forms似乎是合理的。 当它被编译成IL语言时,它与(例如)c#没有什么不同。

这就是说,我会说这是一个更好的词是Transpiling 。 我build议Typescript编译器更好地描述为Transpiler。

这个差别是微妙的,一个转译器可以被认为是一种编译器; 但是(纯粹的)编译语言(通常)将高级语言转换为低级语言(接近机器代码),就像C#示例一样。 译员将高级语言变成(抽象)类似的语言(也是高级语言)。 *

编译代码的结果通常不是您自己编写的语言。 译员的结果是另一种高级语言。 从理论上讲,你可以编写IL(作为一个例子),但它确实是由编译器生成的,没有工具和支持,只能通过编译C#/ vb.net来生成IL。 而Javascript本身就是一种可用(和使用)的编程语言。

*许多警告,因为这些词的定义和它们的用法是非常模糊的

你似乎在一个问三个问题:

  • 编译器和转译器有什么区别?
  • Angular和TypeScript是否实现编译器或转译器?
  • 有没有一个单独的Angular编译器? 它是什么编译?

编译器和转译器有什么区别?

@JörgWMittag为这个问题提供了非常好的答案 。

Angular和TypeScript是否实现编译器或转译器?

TS和Angular都实现了真正的编译器。 他们遵循词法分析,parsing,语义分析和代码生成的相同阶段作为生成汇编代码的C / C ++编译器(可能除了优化)。 你可以看到,这个类/文件夹在Angular和TS中都被命名为“compiler”。

angular度编译器与TypeScript编译器并不真正相关。 这些是非常不同的编译器。

有没有一个单独的Angular编译器? 它是什么编译?

Angular有两个编译器:

  • 查看编译器
  • 模块编译器

视图编译器的工作是将您为组件模板指定的模板转换为组件的内部表示,该组件是用于实例化视图实例视图工厂

除了转换模板之外,视图编译器还以@HostBinding@ViewChild等装饰器的forms编译各种元数据信息。

假设你定义一个组件和它的模板是这样的:

 @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 ',...]) ] 

它描述了组件视图的结构,并在实例化组件时使用。 第一个节点是元素定义,第二个是文本定义。 您可以看到每个节点通过参数列表获取它需要的信息。 解决所有必需的依赖关系并在运行时提供它们是编译器的工作。

我强烈build议阅读这些文章:

  • 以下是您需要了解有关Angular的dynamic组件的信息
  • 这就是为什么你在Angular里面找不到组件的原因

另外,请参阅Angular AOT和JIT编译器之间的区别是什么。

模块编译器的工作是创build一个基本上包含提供者的合并定义的模块工厂。

欲了解更多信息,请阅读:

  • 避免与Angular中的模块共同混淆

打字稿发送到JS。 那么就有树在摇晃,“less”(可选)以及在部署的过程中还有什么。 但是没有什么比这个(afaik)和“编译”有什么关系。 一切都得到了捆绑和大量优化,但实际上并没有编译,对吧?

编译意味着将用语言A编写的程序转换成用语言B编写的语义等同的程序,以便根据语言B的规则评估编译的程序(例如用解释程序来解释B )产生相同的结果并具有与根据语言A的规则对原始程序进行评估相同的副作用(例如用解释器A来解释)。

汇编只是将程序从语言A翻译成语言B. 这就是这个意思。 (还要注意, AB完全可能是相同的语言。)

在某些情况下,对于某些types的编译器,我们有更多的专用名称,具体取决于AB ,以及编译器的function:

  • 如果A被认为是汇编语言,而B被认为是机器语言,那么我们称之为汇编语言,
  • 如果A被认为是机器语言, B被认为是汇编语言,那么我们称之为反汇编
  • 如果A被认为比B更低,那么我们称之为反编译器
  • 如果AB是相同的语言,并且生成的程序以某种方式更快或更轻,那么我们称之为优化器
  • 如果AB是相同的语言,并且得到的程序更小,那么我们称之为缩小器
  • 如果AB是相同的语言,并且生成的程序可读性较差,那么我们称之为混淆器
  • 如果AB被认为是在大致相同的抽象层次上,那么我们称之为一个转译器
  • 如果AB被认为处于大致相同的抽象层次,并且所得到的程序保留了格式化,注释和程序员的意图,从而有可能以与原始程序相同的方式维护结果程序,它是一个重新devise的工具

此外,请注意,较旧的来源可能使用术语“翻译”和“翻译”而不是“编译”和“编译器”。 例如,C谈到“翻译单位”。

您也可能偶然发现“语言处理器”这个词。 这可能意味着编译器,解释器或编译器和解释器,这取决于定义。

JavaScript本身仍然是解释,对吧?

JavaScript是一种语言。 语言是一套逻辑规则和限制。 语言不被解释或编译。 语言

编译和解释是编译器或解释器(duh!)的特征。 每种语言都可以通过编译器来实现,每种语言都可以通过解释器来实现。 许多语言都有编译器和解释器。 许多现代的高性能执行引擎都有至less一个编译器和至less一个解释器。

这两个术语属于不同的抽象层次。 如果英文是一种打字的语言,那么“解释语言”就是一种types错误。

还要注意一些语言既没有解释器也没有编译器。 有些语言完全没有实现。 不过,他们是语言,你可以编写程序。 你只是不能运行它们。

另外,请注意,在某些情况下 ,所有的事情都会被解释:如果你想执行某些事情,你必须解释它。 编译只是将代码从一种语言翻译成另一种语言。 它不运行它。 解释运行它。 (有时候,当一个翻译是用硬件实现的时候,我们称之为“CPU”,但它仍然是一个翻译。)

例如:目前现有的每个主streamJavaScript实现都有一个编译器。

V8作为一个纯粹的编译器开始:它直接编译JavaScript到中等优化的本地机器代码。 之后又添加了第二个编译器。 现在有两个编译器:一个轻量级的编译器,可以产生适度优化的代码,但编译器本身速度非常快,只需要很less的RAM。 此编译器还将分析代码注入编译的代码。 第二个编译器是一个更重,更慢,更昂贵的编译器,然而,它产生更紧密,更快的代码。 它还使用第一个编译器注入的分析代码的结果来做出dynamic优化决策。 此外,决定使用第二个编译器重新编译的代码是基于该分析信息进行的。 请注意,在任何时候都不涉及翻译。 V8从来没有解释,它总是编译。 它甚至不包含口译员。 (实际上,我相信现在是这样,我正在描述前两个迭代。)

SpiderMonkey将JavaScript编译为SpiderMonkey字节码,然后解释它。 解释器还对代码进行剖析,然后最常执行的代码由编译器编译为本地机器代码。 所以,SpiderMonkey包含两个编译器:一个从JavaScript到SpiderMonkey字节码,另一个从SpiderMonkey字节码到本机机器码。

几乎所有的JavaScript执行引擎(V8除外)遵循这种将JavaScript编译为字节码的AOT编译器模型,以及在解释和编译字节码之间切换的混合模式引擎。

你在评论中写道:

我真的以为机器代码是涉及的地方。

“机器代码”甚至意味着什么?

一个人的机器语言是另一个人的中间语言,反之亦然? 例如,有可以本地执行JVM字节码的CPU,在这样的CPU上,JVM字节码本机机器码。 并且有x86机器码的解释器,当你运行那些x86机器码的时候解释字节码的。

有一个用Java编写的称为JPC的x86解释器。 如果我在运行在本地JVM CPU上的JPC上运行x86机器代码…这是字节码,哪个是本地代码? 如果我编译x86机器码到JavaScript(是的,有工具可以做到这一点),并运行在我的手机(它有一个ARM CPU),这是字节码,这是本机机器代码的浏览器? 如果我正在编译的程序是一个SPARC模拟器,我用它来运行SPARC代码?

请注意, 每种语言都会引发一个抽象机器,并且是该机器的机器语言。 所以,每种语言(包括非常高级的语言)都是本机机器码。 另外,你可以为每种语言写一个解释器。 所以,每种语言(包括x86机器码)都不是原生的。

获取您编写的代码在浏览器上运行涉及两件事情:

1)将打字稿转换为JavaScript 。 这是一个解决的问题。 我认为他们只是使用webpack。

2) 将angular度抽象编译成JavaScript 。 我的意思是像组件,pipe道,指令,模板等。这就是angular色核心团队的工作。

如果您真的对第二点感兴趣,那么angular度编译器, watch编译器作者Tobias Bosch在AngularConnect 2016中解释了Angular Compiler 。

我认为在编译和编译之间会出现一些混乱。 它有点不重要,而且是个人品味的问题,它们只是代码之间的转换。 但是我个人使用的定义是,在相似的抽象层次(例如typescript to javascript), 转译是在两种不同的语言之间进行的,而编译需要在抽象层次上下台。 我认为从模板,组件,pipe道,指令等只是JavaScript是一个抽象的阶梯,这就是为什么它被称为编译器。