为什么Angular会有JIT和AOT两种编译方式

lx1036
  • 3.1k

为什么 Angular 会设计出 JIT/AOT 两种编译方式呢?为什么会提供 @angular/platform-browser 和 @angular/platform-browser-dynamic 两个包呢?

我们知道,Angular 提供了 @angular/compiler 和 @angular/compiler-cli 编译器包。JIT(just in time) 是把 compiler 也下载到浏览器里,在浏览器里,在运行时去实时编译 ts 文件中的 Angular components 和 modules,编译成 js 文件;而 AOT(ahead of time) 是在 build 阶段使用 compiler 编译 ts 文件中的 Angular components 和 modules,编译成 js 文件。根据 Medium 上这篇文章来看 Angular: Is AOT Worth It? ,Angular 起初只有 JIT,然后 Tobias BoschMisko Hevery 想到在编译阶段使用 @angular/compiler 和 @angular/compiler-cli 去编译 Angular components 和 modules 代码,才产生了 AOT 编译。所以知道 JIT/AOT 区别仅仅是编译阶段不同,使用的是同一个 @angular/compiler 和 @angular/compiler-cli 编译器编译代码。

官网上也重点描述了 AOT compile ,并且解释了 AOT 的好处及其 Angular 编译器包如何编译代码的。我们开发者在使用 Angular 时,也会借助 @angular/cli 工具使用 AOT 方式去编译代码(现在 @angular/cli 也默认使用 AOT),尽管我们也知道 @angular/cli 内部也是用 @ngtools/webpack 包提供的 ngcLoaderAngularCompilerPlugin 作为自定义 Webpack Loader 和 Plugin 接入到 Webpack 中 ,实现加载和编译 Angular components 和 modules 的目的。

那么,为何 Angular 不废弃掉 JIT 只用 AOT呢,这样不可以简化 Angular 吗?

正是因为 Angular 有 JIT 和 AOT 两种方式,所以针对 browser 平台提供了两个包:@angular/platform-browser-dynamic@angular/platform-browser 。设想如果只有 AOT 方式,岂不是只需要一个包了,这会非常简化 Angular。

在实战中,我想大多数项目都会选择 AOT 方式而不是 JIT 方式。
那么,为何 Angular 不废弃掉 JIT 只用 AOT呢,这样不可以简化 Angular 吗?
那么,为何 Angular 不废弃掉 JIT 只用 AOT呢,这样不可以简化 Angular 吗?
那么,为何 Angular 不废弃掉 JIT 只用 AOT呢,这样不可以简化 Angular 吗?

回复
阅读 4.5k
2 个回答

结论是开发时用JIT而部署时用AOT。
直接原因是开发时会频繁改动代码进而频繁触发编译,如果都使用AOT,将花费比JIT多得多的编译时间,而只享受到编译完成后带来少量(或明显)的交互响应速度的提升,每次代码改动触发的界面刷新都将花费这段比较久的预编译时间,综合下来JIT显然比AOT更适合开发(至少在开发速度上)。
生产环境(即部署时),显然此时不需要频繁调试代码了,那大可以一次性花费较多的编译时间,而让用户享受较快的执行速度。

写包的时候给你举个例子,写自定义包时总需要向你的模块注入自定义配置的对吧,比如服务器url啊,涉及到多态环境时你会想要在运行时判断环境从而执行不同环境的代码
下面是纯静态的模块JIT AOT都无任何毛病

clipboard.png
下面是动态,AOT编译或者 prod编译时直接报错。
clipboard.png
[图片上传中...]