角度编译器“编译”了什么?

时间:2017-10-10 15:22:45

标签: javascript angular typescript angular-cli angular-compiler-cli

我今天被问及无法给出正确答案。

Typescript转换为JS。然后是树摇动,“少”(可选)以及在进行部署的过程中还有什么。但是那些(afaik)与“编译”无关。一切都被捆绑并大量优化,但实际上并没有编译,对吧?

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

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

6 个答案:

答案 0 :(得分:85)

您假设编译意味着获取源代码并生成机器代码,低级代码等。但实际编译只意味着获取一个源代码并将其转换为另一个源代码。所以说使用Typescript和生成JavaScript是编译的形式似乎是合理的。它与编译成IL语言时c#的作用并没有什么不同。

那就是说,我说更好的话就是 Transpiling 。我建议将Typescript编译器更好描述为一个Transpiler。

区别是微妙的,并且可以将转换器视为一种编译器;但是(纯)编译语言(通常)将高级语言转换为低级别语言(更接近机器代码),如C#示例。转换器将高级语言转换为类似的(抽象)语言级别(也是高级别)。 *

编译代码的结果通常不是您自己编写的语言。转换器的结果是另一种高级语言。理论上,您可以编写IL(作为示例),但它实际上是由编译器生成的,并且没有工具或支持来执行此操作,您只通过编译C#/ vb.net来生成IL。而Javascript本身就是一种可用的(和使用过的)编程语言。

*很多警告,因为这些词的定义及其用法非常模糊

答案 1 :(得分:64)

你好像在一个问三个问题:

  • 编译器和转换器之间有什么区别?
  • Angular和TypeScript是否实现编译器或转换器?
  • 是否有单独的Angular编译器?什么编译?
  

编译器和转换器之间有什么区别?

@JörgWMittagprovided a very good answer这个问题。

  

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

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

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

  

是否有单独的Angular编译器?什么编译?

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

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

我强烈建议您阅读这些文章:

另外,请参阅What is the difference between Angular AOT and JIT compiler.

的答案

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

有关详细信息,请阅读:

答案 2 :(得分:16)

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

1)将 Typescript展示为JavaScript 。这是一个解决的问题。我认为他们只是使用webpack。

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

如果您真的对第二位感兴趣,那么角度编译器watch compiler author Tobias Bosch explain the Angular Compiler at AngularConnect 2016

我认为在转换和编译之间会有一些混乱。它有点无关紧要并且是个人品味的问题,它们只是在代码表示之间进行转换。但我个人使用的definition transpilation 介于两种不同语言之间,处于类似的抽象级别(例如打字稿到javascript),而编译需要降级在抽象层次。我认为从模板,组件,管道,指令等只是javascript是抽象阶梯的一步,这就是它被称为编译器的原因。

答案 3 :(得分:0)

Angular编译器

从Angular 4到5的最重要的变化之一是编译器被重写得更快,更彻底。过去,Angular应用程序使用我们所谓的即时(JIT)编译,即在运行时在浏览器中运行该应用程序之前对其进行编译。 Angular 5中的编译器更新促进了向AOT的迁移,这使应用程序运行得更快,因为它在运行应用程序时执行较少的编译。从Angular CLI的1.5版本开始,在任何生产版本中默认都会启用AOT。

假设我们要构建一个用于部署的应用程序并运行以下命令:

ng build --prod

发生了一些事情:生产版本,缩小版本,捆绑资产,文件名哈希,摇树,AOT ...(我们可以使用标志启用/禁用此功能,例如aot = false)。简而言之,prod标志通过使用 ngc (Angular编译器)进行AOT编译来创建应用程序的优化捆绑,以创建适合浏览器的优化代码(是,它会预先编译)模板)。

TypeScript编译器

TypeScript编译器 tsc ,负责编译TypeScript文件。是由编译器负责实现TypeScript功能(例如静态类型),结果是纯JavaScript,其中删除了TypeScript关键字和表达式。

TypeScript编译器具有两个主要功能:它是一个编译器和一个类型检查器。编译器将TypeScript转换为JavaScript。它会对您的源代码进行以下转换:

  • 删除所有类型注释。
  • 为旧版本的JavaScript编译新的JavaScript功能。
  • 编译不是标准JavaScript的TypeScript功能。

调用它,编译器将搜索tsconfig.json中加载的配置(所有编译器选项的详细列表以及默认值,可以在here中找到)。

在大多数方面,TypeScript编译器的工作方式与任何编译器一样。但是有一个区别可以解决这个问题:默认情况下,即使遇到错误,编译器仍继续发出JavaScript代码。幸运的是,可以通过在tsconfig.json文件中将noEmitOnError配置设置设置为true来禁用此行为。

要注意 tsc ngc 具有不同的用途,而不是一个选择另一个。 This answer might be of interest

此答案是根据以下书籍中的内容制作的

  • Cloe,M.(2018年)。 “ Angular 5项目:学习使用70多个项目构建单页Web应用程序”。

  • 杜威(Dewey),B。格罗斯尼克劳斯(Grossnicklaus),K. “使用Visual Studio 2017构建Web应用程序:使用.NET Core和现代JavaScript框架”。

  • Freeman,A.(2019年)。 “基本打字稿:从初学者到专业人士”。

  • Ghiya,P.(2018)。 “ TypeScript微服务”。

  • Iskandar,A.,Chivukulu,S.(2019年)。 “使用Angular和Bootstrap进行Web开发-第三版”。

  • Hennessy,K.,Arora,C.(2018年)。 “示例角度6”。

  • Jansen,R.,Wolf,I.,Vane,V.(2016年)。 “ TypeScript:现代JavaScript开发”。

  • Mohammed,Z.(2019年)。 “ Angular项目”。

  • Seshadri,S.(2018年)。 “ Angular:启动并运行”。

  • Wilken,J.(2018年)。 “行动中的角度”。

答案 4 :(得分:-2)

有关更多详细信息,请遵循:https://en.wikipedia.org/wiki/Angular_(web_framework)

  
    

我假设这不是编译器或解释器的问题,或者     转译器。

         

所有这些词都用于识别其执行的级别     转换过程及其执行方式。

  
     

例如:请软件开发人员,高级软件开发人员和软件   团队负责人。

     

对于所有这三个角色,实际工作发展,但是   复杂度根据人的角色而变化

请使用我用的“编译或编译器”这个词来解释这个特定问题。

我不会深入探讨不同类型的代码转换。

Straight answer to your question is: 
  

角度没有编译器。因为它不是语言

     

但是打字稿有一个编译器,其中使用 angular库/ Framework语言   是

因为它没有编译器,所以不能编译任何东西。

1。)' Angular '(2.x及更高版本)是使用称为 typescript 的语言编写的库/框架

2。)相反,“ angularjs ”(1.x版本)是使用称为 java脚本的语言编写的库/框架

为什么要编译:

由于angular是使用打字稿编写的,因此浏览器不知道(这是为Web应用程序运行功能代码的实际平台)。

因此,通过使用 typescript编译器,角度组件将转换为浏览器可理解的Java脚本组件。

答案 5 :(得分:-5)

为每个人提供建议:始终始终以定义开始响应(和研究)! MERRIAM-WEBSTER词典... 编译:动词 计算机:“将(计算机编程说明)更改为计算机可以理解和使用的形式”

维基百科... 编译器是一种计算机软件,它将以一种编程语言(源语言)编写的计算机代码转换为另一种编程语言(目标语言)。编译器是一种支持数字设备(主要是计算机)的翻译器。名称编译器主要用于将源代码从高级编程语言转换为低级语言(例如,汇编语言,目标代码或机器代码)以创建可执行程序的程序。[1]

讨论: 韦伯斯特词典在这里应该被认为是最高权威,但是其定义却令人困惑。

维基百科确实也是事实上的权威资料。如果在这种情况下,我们认为其解释为上级权威,则它会(通常)竭尽全力提供一些真正有用的见解,尤其是以下内容:

  1. 从最严格的意义上讲,编译的意思是“将不能直接由计算机执行的语言的编程代码转换成可以由计算机直接执行的代码。
  2. 如果我们接受以上内容作为“编译”的真正定义... 如果在Angular中发生的一切只是将Typescript转换为Javascript ... 如果Javascript代码仍然需要将“解释”转换为字节码... 如果字节码然后由node.js解释为计算机可执行的代码... 然后,Angular所做的事情并没有真正意义上的“编译”。期。

说...

  1. 如果我们放松对“编译”的定义,仅表示“将编程代码从高级语言转换为低级语言” ... 如果我们接受Typescript是比Javascript更高的语言(在许多方面)... 然后,Angular所做的(将Typescript转换为Javascript)是“正在编译” ...

说...

  1. 如果我们引入了一些新的编译类型(根据Wikipedia):
    • 编译:将代码从高级语言翻译为低级语言;
    • 翻译:在本质上“等效”的语言之间翻译代码;和
    • 反编译:将代码从低级语言转换为高级语言; 然后,Angular是“编译”还是“转换”取决于您是否接受Typescript是(甚至略微)比Javascript更“高级”的语言的断言。

我吗? 一种。我更喜欢编译的“工作定义”是“从高到低的翻译”;    (它更加笼统,为定义的演变留出了空间) b。我的确也认为Typescript是比Javascript更高的语言。所以 C。我对Angular断言它是“正在编译”很好

该替代品是不可取的: 如果我们要求“编译”必须表示“翻译为'可执行'代码”; 如果我们接受Typescript比Java脚本“高”的话; 然后,Angular ISN不“编译”:-|但 Angular ISN甚至都不会“编译” :-(! 实际上,我们甚至无法描述Angular正在使用可用的词汇表!

因此,我将“编译”的定义“一般化”(读为“放松”),仅表示“从较高到较低”,而不是“从较高到机器”,现在我的可用词汇可以描述Angular是什么这样做-它是“正在编译”

如果此讨论的目标是加强了解,那么我希望我自己的少量捐赠对某些人有用。

干杯, -在北伊罗拉(North Aurora IL)标记