Angular
首发于Angular
Angular 9.0 发布!Ivy 正式抵达!

Angular 9.0 发布!Ivy 正式抵达!

翻译自:blog.angular.io/version

翻译版原始链接:Angular 9 现已推出 - Ivy 已抵达!

版权声明:本文章遵循 CC-BY 协议(署名、共享、演绎),您可以在保持署名的前提下自由转载,而不必联系我,也不必支付报酬。

P.S. Angular 开发组为这次升级准备了一场盛大的直播庆祝活动,在北京时间周六凌晨一点开始,想参加的请访问 youtube.com/watch?。还有十三个小时了哦,想看的请准备好梯子。

Angular 的 9.0.0 版本发布了!这是一个跨平台的主版本,包括框架、Angular Material 和 CLI。这个版本默认会把应用程序切换到 Ivy 编译器和运行时,并改进了组件测试方法。

这是 Angular 在过去 3 年中所做的最重大更新之一,我们很高兴能通过各种方式帮助开发人员构建出更好的应用并为 Angular 生态系统做出贡献。

如何更新到版本 9

访问 update.angular.io,获取详细信息和升级指导。为了获得最佳的更新体验,我们建议你先升级到 Angular 8 的最终版。

首先,更新到 8 的最新版本

ng update @angular/cli@8 @angular/core@8

然后,升级到 9

ng update @angular/cli @angular/core

要查看使用此更新内容的关键修改(包括已弃用了哪些 API),请参阅 Angular 文档中的“更新到 Angular 9 ”。

Ivy(常春藤)

默认情况下,版本 9 会把所有的应用程序迁移成使用 Ivy 编译器和运行时的。除了数以百计的 bug 修复之外,Ivy 编译器和运行时还提供了许多优点:

  • 打包尺寸更小
  • 测试速度更快
  • 更好的调试
  • 改进了 CSS 类和样式绑定
  • 改进了类型检查
  • 改进了构建错误
  • 缩短了构建时间,默认启用了 AOT
  • 改进了国际化支持

下面是一些比较值得注意的改进项。

打包尺寸更小

Ivy 编译器的设计目的是删除那些无法通过摇树优化使用的 Angular 部件,并为每个 Angular 组件生成更少的代码。

通过这些改进,小型应用和大型应用可以节省大量成本。

  • 那些没用多少 Angular 特性的小应用从摇树优化中受益最多。
  • 包含很多组件的大型应用从减小的工厂函数体积中受益最多。
  • 中等大小应用的包体积可能只会小一点点,因为它们从摇树优化中受益较少,并且没有足够的组件从减小的工厂函数体积中受益。

测试速度更快

我们还改进了 Ivy 中 TestBed 的实现,以提高效率。

以前,TestBed 会在运行每个测试之间重新编译所有组件,而不管组件是否有任何变化(例如,通过覆写)。

在 Ivy 中,除非已经手动覆盖了一个组件,否则 TestBed 不会在这些测试之间重新编译组件,这样就可以避免大多数测试间的重新编译。

有了这项更改,框架的核心验收测试速度提高了大约 40%。我们期待用户自己的应用测试速度也能提高 40-50%左右。

更好的调试

Ivy 为你提供了更多调试应用的工具。当我使用 Ivy 运行时在开发模式下运行应用时,我们现在提供了新的全局对象 ng 来进行调试。

  • 你可以要求 Angular 访问你的组件、指令等实例
  • 你可以手动调用各个方法并更新状态
  • 如果要查看变更检测的结果,可以使用 applyChanges 来触发变更检测

Ivy 还改进了用于调试问题的调用栈跟踪,比如 ExpressionChangedAfterItHasBeenCheckedError 。以前堆栈跟踪可能没多少帮助:

在 Ivy 中,你可以看到一个更实用的调用栈跟踪,它允许你直接从一个已更改的表达式跳转到模板指令。

例如,如果在上面的堆栈跟踪中单击 AppComponent_Template,就可以在生成的代码中看到抛出该错误的具体代码行:

如果愿意,你还可以进入任何一个框架指令,来了解框架是如何创建或更新你的组件的。

改进了 CSS 类和样式绑定

Ivy 编译器和运行时改进了处理样式的方式。以前,如果一个应用程序包含了对某种样式的竞争性定义,那些样式就会破坏性地相互覆盖。在 Ivy 中,样式将以可预测的方式合并在一起。

考虑下面的模板和组件片段:

<my-component style="color:red;" [style.color]="myColor" [style]="{color: myOtherColor}" myDirective></div>
@Component({
  host: {
    style: "color:blue"
  },...
})
...

@Directive({
  host: {
    style: "color:black",
    "[style.color]": "property"
  },...
})
...

以前,被最后计算出的那种绑定会胜出,而这可能取决于对这些表达式的修改时机。而如果 myColormyOtherColor 都是未定义的,静态的'red'样式就会被忽略。

在版本 9 中,你可以通过一个清晰、一致的优先顺序来管理你的样式,而这些顺序与时间无关。最具体的样式始终具有最高的优先级。例如,对 [style.color] 的绑定会覆盖 [style] 中的同名绑定。

但是,出于向后兼容性的考虑,我们仍然把 [ngStyle][ngClass] 的绑定行为保持原样。也就是说,它们的绑定值发生变化时,新值会覆盖任何竞争性绑定。

你可以在文档中的模板语法一章阅读更多关于样式优先级规则的内容。

作为样式重构的一个额外收获,你现在也可以绑定 CSS 自定义属性(也叫 CSS 变量)了。

<div [style. -- main-border-color]=" '#CCC' ">
<p style="border: 1px solid var(--main-border-color)">hi</p>
</div>

改进了类型检查

Angular 编译器可以检查应用中的更多类型,还可以应用更严格的规则。这些特性可以帮助你和你的团队在开发过程的早期阶段发现 bug。

除默认值外,我们还支持两个主要的标志来进行额外的类型检查:

  • fullTemplateTypeCheck - 激活这个标志会告诉编译器要检查你模板中的所有内容( ngIfngForng-template 等)
  • strictTemplates - 激活这个标志会在类型检查中使用最严格的类型系统规则。

要了解有关模板类型检查选项的更多信息,请参阅文档中的模板类型检查指南

改进了构建错误

新的 Ivy 编译器不仅运行速度更快、有更强大的类型安全性,而且还能让所有的错误信息更容易阅读。

在版本 8 或 View Engine 中,典型的编译器错误如下所示:



在使用 Ivy 的 9 版本中,同样的错误如下:



缩短了构建时间,默认启用了预先编译器(AOT)

感谢 Ivy 的新架构,我们对编译器的性能做了很大的改进。

我们会根据应用中普通的 TypeScript 编译开销来衡量编译器的性能。对于我们的文档应用(angular.io)来说,使用 Ivy 时,这个开销从 0.8 倍减少到了 0.5 倍,提升了近 40%。

这些改进意味着 AOT 构建的速度可以显著加快。感谢这次加速,我们第一次在开发模式下使用 AOT。这意味着 ng serve 现在可以从与构建时相同的编译期检查中获益,从而大大提高了 Angular 的开发体验。

由于编译器和运行时都发生了变化,我们也不再需要 [entryComponents](https://angular.cn/guide/deprecations#entryComponents) 。这些组件全都会根据用途被自动发现和编译。

改进了国际化支持(i18n)

国际化已经成为 Angular 的核心特性,你可以在每个语言环境中构建一次应用,并收获高度优化的本地化应用。在 9.0 中,我们通过把 i18n 的工作移到构建过程的后期实现了这一目标。这种变化让我们能把它提速 10 倍。

阅读更多 以了解关于新 i18n 中 @angular/localize 和新的 angular.json 配置的信息。

版本 9 还有其它一些改进

该团队还努力工作,不断提升使用 Angular 的全部体验。

更可靠的 ng update

我们对 ng update 工作方式进行了一些修改,以提高它的可靠性和信息量。

  • 始终使用最新的 CLI。从 CLI 的 8.3.19 版本开始,我们现在在升级过程中使用了 TARGET 版本的 CLI。这意味着,在未来,更新将始终由最新的 CLI 自动处理。
  • 进度更新更清晰ng update 现在做了更多的工作来告诉你幕后的情况。对于每次迁移,你都会看到迁移中的更多信息。
  • 更容易对更新进行调试。 默认情况下,ng update 运行所有迁移,并在磁盘上留下最终结果更改供你检查。版本 9 的更新还引入了新的 --create-commits 标志。当你运行 ng update --create-commits 时,该工具会在每个迁移动作后提交代码库的状态,这样你就可以逐步理解或调试我们对代码所做的更改。

providedIn 的新选项

当你在 Angular 中创建一个 @Injectable 服务时,你必须选择它应该添加到注入器的什么位置。除了以前的 root 和模块这两种选项之外,还有两个新选项。

  • platform - 指定 providedIn: 'platform' 可以在一个特殊的单例平台注入器中使用该服务,该注入器由该页面上的所有应用共享。
  • any - 在每个注入该令牌的模块(包括惰性加载模块)中提供一个唯一的实例。

请到我们的 API 文档中了解详情

组件的测试挽具

历史上,测试组件一直靠 CSS 选择器这样的实现细节来查找组件和触发事件。这意味着只要组件库改变了它的实现,就需要更新依赖这些组件的所有测试。

在版本 9 中,我们引入了组件的测试挽具,它提供了另一种测试组件的方法。通过抽象出实现细节,你可以确保你的单元测试被正确的局部化,而且不那么脆弱。

现在,Angular Material 的大多数组件都可以通过这些挽具进行测试,而且我们还会把这些挽具作为组件开发套件 (CDK)的一部分提供给任何一位组件作者。

这是一个在使用组件挽具之前的一个测试范例:

it("should switch to bug report template", async () => {
  expect(fixture.debugElement.query("bug-report-form")).toBeNull();
  const selectTrigger = fixture.debugElement.query(
    By.css(".mat-select-trigger")
  );
  selectTrigger.triggerEventHandler("click", {});
  fixture.detectChanges();
  await fixture.whenStable();
  const options = document.querySelectorAll(".mat-select-panel mat-option");
  options[1].click(); // Click the second option, "Bug".
  fixture.detectChanges();
  await fixture.whenStable();
  expect(fixture.debugElement.query("bug-report-form")).not.toBeNull();
});

而用组件挽具做同样的测试如下:

it("should switch to bug report template", async () => {
  expect(fixture.debugElement.query("bug-report-form")).toBeNull();
  const select = await loader.getHarness(MatSelect);
  await select.clickOptions({ text: "Bug" });
  expect(fixture.debugElement.query("bug-report-form")).not.toBeNull();
});

了解更多关于 Material 的组件测试挽具或用 CDK 构建你自己的挽具

新的组件

你现在可以在应用中添加来自 YouTube 和谷歌地图的功能了。

  • 你可以使用全新的 youtube-player ,在你的应用中内嵌 YouTube 播放器。当你加载了 YouTube 的 IFrame 播放器 API 之后,这个组件就会利用它。
  • 我们还推出了 google-maps 组件。利用这些组件,你可以轻松地渲染谷歌地图,显示地标,并像普通的 Angular 组件一样与其交互,让你无需学习完整的 Google Maps API 即可使用。

IDE 和语言服务改进

Visual Studio Marketplace 上的 Angular 语言服务扩展已做了重大改进。随着对性能和稳定性问题的重大架构变革,许多长期存在的漏洞也得到了修复。还包括一些新特性:

  • Angular 模板语法的 TextMate 语法定义,现在可以在内联和外部模板中启用语法高亮显示了
  • 针对 templateUrlstyleUrls 的“转到定义”功能
  • 悬浮工具提示中的 NgModule 和类型信息

TypeScript 3.7 支持

Angular 已经更新,可以用 TypeScript 3.6 和 3.7 了,也包括 TypeScript 3.7 中非常受欢迎的可选串联(optional chaining)特性。为了与生态系统保持同步,我们还更新了其他生态系统依赖的版本,比如 Zone.JS 和 RxJS。

谢谢社区

这个版本是两年多来工作的结晶。我们对这项工作的未来和可能性感到非常兴奋。如果没有社区数百人的努力,这是不可能实现的。

v9 贡献者:

Aaron Frost, Adam J. Penn, Adam Plumer, Adam Vigneaux, Adrien Crivelli, Ajit Singh, Alain Chautard, Alan Agius, Alexander Ivanov, Alexander von Weiss, Alex Eagle, Alex Rickabaugh, alexzuza, Ali Mirlou, Alison Gale, Alyssa Nicoll, Amadou Sall, AMarinov, Amit Dubey, Anders Kjær Damgaard, Andrew Kushnir, Andrew Scott, Andrew Seguin, Andrius, Andrus Diaz, Ankit Prajapati, Aravind, Aristeidis Bampakos, Arne Hoek, Artur Androsovych, arturovt, Atef Ben Ali, Ayaz Hafiz, Ben Elliott, Benjamin Liii, Brian Michalski, CaerusKaru, Carlos Ortiz García, Cédric Exbrayat, Charles Lyding, Christian Liebel, Christopher Dahm, codingnuclei, Colum Ferry, Craig Spence, cran-cg, crisbeto, Cyrille Tuzi, Daniele Morosinotto, Daniel Waxweiler, Danny Skoog, David Sánchez, David Shevitz, Denis Omelkov, Denys Vuika, Diego Juliao, dishanfernando, Dmitri Ischenko, Dominik Pieper, Do Nhu Vy, Doug Parker, Dyma, EddyP23, Edy Segura, Eliran Eliassy, Elvis Begovic, Emmanuel DEMEY, Ephraim, Erik Pintar, Esteban Gehring, Eusen, Evan Martin, FabianGosebrink, FaustmannChr, FDIM, Ferdinand Malcher, FG-33, Filipe Silva, Gabor Szekely, Gabriel Medeiros Coelho, GavinMK, Geoff Bass, George Kalpakas, Gérôme Grignon, ghiscoding, Girma Nigusse, Greg Magolan, Grigoriy Beziuk, hafiz, Harinder Singh, Hayouung, Hoel IRIS, horn, idzark, Igor Minar, Issei Horie, ivanwonder, Jakub Pawlot, James Vickery, Jan Malchert, Jason Bedard, Jeff Held, Jennifer Fell, Jeremy Elbourn, JiaLiPassion, Jithil P Ponnan, jnavb, Joakim Zebic, Joey Perrott, john li, John Ralph Umandal, Jonathan Sharpe, Joost Koehoorn, Jordan Amman, Jordan Nelson, Joshua Colvin, Judy Bogart, J Z, Kai Röder, Kapunahele Wong, Kara Erickson, katryo, Kayla Altepeter, Keen Yee Liau, ketangote, Kirk Larkin, Koala, Kristina Gocheva, kristinavavrova, Kristiyan Kostadinov, Kwinten Pisman, Kyle J. Kemp, Lars Gyrup Brink Nielsen, LASLEDJ, lazarljubenovic, Leonardo Zizzamia, Leon Radley, Luka Petrovic, Mansour Fall, manzonif, Mark Goho, Martina Kraus, Martin Probst, Matias Niemelä, Matthew Harris, Matt Janssen, Mayur Barge, mbehrlich, mertdeg2, Michael Maier, Michael Nahkies, Michael Prentice, Michał Koziara, Mike Brocchi, Mike Casebolt, mikef, Miles Malerba, Minko Gechev, Mirco Widmer, Misko Hevery, Miško Hevery, Mitchell Skaggs, mohax, Muhammad Umair, Muhammad Umair Khan, Nathan Tate, Németh Tamás, Nicolas Villanueva, Nikita Potapenko, Niklas Merz, noeri, Noopur, NothingEverHappens, ODAVING, Olegas Goncarovas, Olivier Combe, Orlando Pozo, owenmecham, Pascal Fivian, paulceli, Paul Gschwendtner, Pawel Kozlowski, Pete Bacon Darwin, Phaneendra, philonor, Pierre-Yves FARE, Piotr Błażejewicz, Potapy4, Rado Kirov, Ralf D. Müller, Raz Luvaton, Reuben Wilson, Richard Lea, Rick Katka, Robert Coie, Robin Dupret, Roy, Rudar Daman Singla, Rustam, Sachin, Sahan Serasinghe, Sam Julien, Santosh Yadav, Sasha Rudan, Sergey Koshechkin, Sergey Nikitin, Shibasish, Sholka Jadav, Showtim3, ShubhrankR, Simon Jespersen, Simon Kurtz, skrikl, Smartin, Sonu Kapoor, Srichandradeep Choudarapu, Sriram Jayarman, Stefanie Fluin, Stephen Cooper, Stephen Fluin, Suguru Inatomi, Suresh918, Syu Kato, thanhpd, thekiba, TheMushr00m, Tiep Phan, Timar, Tim Deschryver, TinyMan, Tom Kwong, Tom Sullivan, Trevor Karjanis, Troels Lenda, Turtuvshin Byambaa, Vanessa Schmitt, Victor, Vikash Dahiya, Vikram Subramanian, Wagner Maciel, Wataru Kasahara, Wenqi, why520crazy, willbeaufoy, William Lohan, WreckItRalph, Yann Bertrand, Younes Jaaidi, Yulia Tsareva, Zaid Al-Omari, zuckjet, 陈旭.

我们还要感谢我们的 GDE 和整个社区。我们收到的反馈、问题报告和问题重现项目(Reproductions)对于让我们的工作达到最高质量标准至关重要。使用版本 9 的公开 Angular 应用已经超过了 4000 个。

特别要感谢我们的长期企业合作伙伴 Pawel Kozlowski 和他的赞助商 Amadeus。在 Ivy 项目的两年时间里,帕维尔以极高的品质做出了巨大的贡献,这是该项目成功的关键部分。

如果您对本次发布有任何意见和建议,请提出 Issue ,或者告诉我们

编辑于 2020-02-07

文章被以下专栏收录