Angular v8 发布!来看看有什么新功能[每日前端夜话0x7A]

Angular v8 发布!来看看有什么新功能[每日前端夜话0x7A]

疯狂的技术宅 前端先锋 html

每日前端夜话0x7A
每日前端夜话,陪你聊前端。
天天晚上18:00准时推送。
正文共:3332 字
预计阅读时间: 8 分钟
翻译:疯狂的技术宅
来源:jaxenter前端

Angular v8 发布!来看看有什么新功能[每日前端夜话0x7A]

Angular算法

Angular 8 终于来了,包括 Ivy 的预览、service worker 支持,差别化加载以及一些锦上添花的东西。 Manfred Steyer 解释了最新 Angular 版本中最重要的变化。json

Angular 8 刚刚发布!浏览器

彻底按照计划,没有任何意外:框架和 CLI 的更新能够经过 ng update 完成,其新功能是一个受欢迎的补充,符合“演化而不是革命”的座右铭。网络

在本文中,我将介绍 Angular 8 和 Angular CLI 8 的最重要的新功能。我在文中的例子能够在 GitHub 上找到。app

先瞅一眼 Ivy


Ivy 是 Angular 世界下一个望眼欲穿的大新闻,它是新的 Angular 编译器,也是新的渲染管道。Ivy 有可能产生至关小 bundle,它使渐进式编译更容易,也是 Angular 领域将来创新的基础。框架

因为 Angular 大量的底层部分已经为此进行了更改,所以 Angular 团队特别注意与之前的 Angular 版本的兼容性:在切换到 Ivy 以后,现有的程序应该可以像之前同样工做。在一切正常的前提下,可以获得明显更小的 bundles 应该就足够了。这并不是是他们大发善心,而是由于 Google 有 600 多个以 Angular 为基础的应用程序 —— 尽管是谣传,但实际数字要高得多。异步

在 Angular 8 中 Ivy 的预览版如今可供测试。此版本的目标是得到早期反馈。所以,Angular 团队建议不要把 Ivy 用于生产环境,而是继续使用经典视图引擎(图1)。ide

Angular v8 发布!来看看有什么新功能[每日前端夜话0x7A]
使用与不使用 Ivy 时的 hello world 程序的 Bundle 大小(来源:由Brad Green和Igor Minar撰写的 ngconf 2019 主题演讲)
感谢差别加载(以下所示),bundle 大小已经能够当即获得优化。

正如 Google Angular 团队背后的技术总监 Brad Green 在 ngconf 2019 中提到的那样,Ivy 将在兼容模式下结合差别加载,显着改善 bundle 的尺寸。寻求刺激的人能够尝试一下将来的 Ivy API。该模式下有很是大的优化潜力。目前这些 API 仍然被标记为私有。你能够经过查看它的类和函数来进行判断:它们以特殊字符 ɵ 开头。

若是你想尝试 Ivy,能够经过 enable-ivy 开关生成一个新项目:

1ng new ivy-project --enable-ivy

这样作的结果是 CLI 会在 tsconfig.app.json 中存储如下配置条目:

1"angularCompilerOptions": { 
 2        "enableIvy": true 
 3}

在更新到 Angular 8 以后,也能够手动添加此条目,以便用 Ivy 测试现有程序。

要在调试模式下运行程序,建议使用 AOT:

1ng serve --aot

此外,值得一提的是经过 ng build 建立的程序的大小。等到 Angular 9 发布时 Ivy 最终应该会默认激活。在此以前,Angular 团队计划采起进一步措施以确保与旧版本的兼容性。

Web worker

根据定义,JavaScript 是单线程的。所以,对于数据调用等较大任务异步处理是很常见的。不用说,这对计算密集型没有帮助。特别是那些普遍的 JavaScript 解决方案变得愈来愈广泛,这就是为何如今几乎全部的浏览器都支持支持 Web worker。它们是浏览器在本身的线程中运行的脚本。经过发送消息与浏览器选项卡中的线程进行通讯。

虽然 Web worker 自己与 Angular 无关,但在构建过程当中必须考虑它们。目标是为每一个 Web worker 提供一个 bundle 包。此任务由新的 Angular CLI 完成。

为了说明这个新功能,我将经过实现所谓的 “n 皇后问题”的 JavaScript 进行说明。这个想法是在棋盘上每行放一个皇后,而不能相互公鸡。这意味着在同一行、列或对角线中不能有其余皇后。

Angular v8 发布!来看看有什么新功能[每日前端夜话0x7A]
n皇后问题的一种解决方案
计算棋盘上全部可能的解决方案的算法被认为是计算密集型的。虽然对有 8 行和 8 列的常规棋盘的计算至关快,可是普通计算机从 12×12 格开始就达到了其极限。当前最高记录是解决具备 27 x 27 格的解决方案。俄罗斯的超级计算机完成了此任务。

为了将相似这样的计算甩给后台,咱们必须首先用 Angular CLI 建立 一个Web worker:

1ng generate worker n-queens

此语句不只为 worker 建立文件,还为构建过程和现有文件中的条目建立配置文件。若是同一文件夹包含具备公共文件扩展名 .component.ts 的同名组件,则 CLI 甚至会使用与 Web worker 通讯的代码对其进行丰富。

worker自己只包含 message 事件的事件监听器:

1import nQueens from './n-queens';
2
3addEventListener('message', ({ data }) => {
4  const result = nQueens(data.count);
5  postMessage(result, undefined);
6});

当主线程向 worker 发送消息时会执行该事件。该参数包含从主线程发来的信息。在当前的状况下,它仅限于属性 count ,它声明了棋盘大小。在计算函数 nQueens 以后,事件监听器经过 postMessage 将结果发送回主线程。*所以,浏览器在那里触发 message 事件。

Worker 类被应用于 using 组件来与此 worker 脚本交互:

1const count = parseInt(this.count, 10);
 2
 3const worker = new Worker('../logic/n-queens.worker', {
 4    type: 'module' // Worker uses EcmaScript modules
 5});
 6
 7worker.postMessage({count});
 8
 9worker.addEventListener('message', (event) => {
10  // tslint:disable-next-line: no-console
11  console.debug('worker result', event.data);
12
13  // Update chessboard
14  this.proce***esult(event.data);
15});

组件经过 postMessage 向 worker 发送带有所需棋盘大小的消息,从而触发计算。它经过消息事件接收结果。

最后 CLI 负责将工做脚本正确的转换和捆绑。由此启动的 TypeScript 编译器会经过它们的后缀 .worker.ts 来识别它们,它们在由 ng generate worker 生成的 tsconfig.worker.json 中注册。为了确保 CLI 在翻译和捆绑主程序时再也不考虑这些文件,ng generate worker 将相同的文件模式放在 tsconfig.app.json 的 exclude 部分中。

完整的实现包含在做者的样本集[1]中。为了便于说明,能够在主线程和 Web worker 中解决可用的 n 皇后问题。例如,当你为 12 x 12 棋盘请求解决方案时,你将看到 UI 在第一种状况下会被冻结,而 worker 的后台计算不会下降 UI 的可操做性。

差别加载

目前将程序编译成旧 ECMAScript 5 代码仍然是很常见的,由于“古老的 JavaScript ”在今天仍然在处处运行。这意味着 IE 11 和 Google 搜索引擎后面的网络爬虫均可以执行这些代码。

可是,新的 ECMAScript 2015 及其后续版本更加高效:这些版本容许更紧凑的 bundle 包,浏览器也能够更有效地解释它们。

从版本 8 开始,CLI 包含一个名为差别加载的功能。其背后的想法是提供两组 bundle:一组基于 ECMAScript 5 而且针对较旧的浏览器,另外一组基于较新的 ECMAScript 版本,例如 ECMAScript 2015,以此为现代浏览器提供上述优点。

要激活差别加载,你不用作太多的事情:只须要为 ECMAScript 版本设置一个上限和下限。在 tsconfig.json 中输入版本上限,以下所示:

1"target": "es2015"

另外一方面,下限由浏览器列表来定义。根据市场份额等特定标准,它是一个用来标识许多支持的浏览器的文件。它们能够存储在例如 browserslist 文件中,CLI 在生成新项目时同时会在 projectroot 中建立:

1> 0.5%
2last 2 versions
3Firefox ESR
4not dead
5IE 9-11

以下图所示,browserslist 指向 ECMAScript 5 浏览器,条目为 IE 9-11。所以,CLI 将下限肯定为此版本。若是 CLI 收到构建( ng build)指令,则将对两个版本进行编译和 bundling 过程:

Angular v8 发布!来看看有什么新功能[每日前端夜话0x7A]
构建差别加载
这个过程的缺点显而易见:构建过程所需的时间加倍。

为了使不一样的浏览器能够决定要加载哪一个版本的 bundle 包,他们在 index.html 添加中接受 script 的引用:指向 ECMAScript 5 包的那些引用会添加 nomodule。这可使支持 ECMAScript 2015 及更新版本的浏览器忽略这些引用。另外一方面,ECMAScript 2015+ bundle 包由 CLI 经过 type ="module" 实现。所以旧版浏览器将忽略这些脚本标记:

1<script src="main-es2015.js" type="module"></script>
2
3<script src="main-es5.js" nomodule></script>

与 ng build 相比,其余全部 CLI 命令仅使用上限。在上图中所示的这种状况下,是 ECMAScript 2015。出于效率缘由,会发生这种状况:特别是在调试和测试期间,开发人员但愿尽快看到结果,而不须要等待第二次构建。

延迟加载

自 Angular 出现的第一天起,路由就支持延迟加载。到目前为止,这是经过识别加载模块的魔术值来完成的:

1{
2    path: 'lazy',
3    loadChildren: () => './lazy/lazy.module#LayzModule'
4}

“#”号以前的值表示通向模块实现的文件的路径;以后的值表明其中包含的类。这种写做风格也适用于 Angular 8,可是已经被弃用了,如今支持动态 ECMAScript 导入:

1{
2    path: 'lazy',
3    loadChildren: () => import('./lazy/lazy.module').then(m => m.LazyModule)
4}

新的书写风格中仍然包含文件名做为魔术值。可是因为许多IDE支持导入,所以无效值将当即返回错误。

ViewChild 和 ContentChild 中的重大变化

ViewChild 和 ContentChild 的使用方式发生了重大变化,但遗憾的是,过去并不老是表现出一致的行为。虽然它们在早期版本中被用于组件请求不在结构指令内的元素,如 ngIf 或 ngFor,但查询结果已在 ngOnInit 中可用。不然,程序代码或过早的能够在 ngAfterViewInit(或 ngAfterContentInit for ContentChild )中访问它。对于之后因数据绑定而仅加载到 DOM 中的元素,程序代码必须分别插入 ngAfterViewChecked 或 ngAfterContentChecked。

因为这种行为十分使人困惑,因此如今组件必须指定什么时候应该进行解决:

1@ViewChild('info', { static: false })
2  paragraph: ElementRef;

若是 static 的值为 true,则 Angular 会在初始化组件时尝试查找该元素。这只在不在结构指令中时才有效。使用 static:false 时,在启动或刷新视图后进行解析。

ng update 命令 会自动尝试在此处输入正确的值。若是没法作到这一点,则会在其位置添加带有 TODO 的注释。

与相关装饰器 ViewChildren 和 ContentChildren 的查询不受此更改的影响。他们老是表现出 static:false 意义上的动态行为。

ngUpgrade的新功能

到目前为止,AngularJS 1.x 和 Angular 与 ngUpgrade 的混合操做中存在的一个问题是:两个框架的路由有时一直在争夺 URL。这致使了难以理解的反作用。为了不这种状况,可使用相同的 Location 服务去访问两个版本框架中的 URL 。

为实现这一目标,Angular 团队扩展了Angular Location 服务的可能性,从而为 AngularJS 中的 $location 提供了替代。

出于这个缘由,在 Location 服务中添加了用于监视URL更改的新方法 onUrlChange 以及其余修改:

1export class AppComponent {
2  constructor(loc: Location, pLoc: PlatformLocation) {
3    loc.onUrlChange((url) => console.debug('url change', url));
4    console.debug('hostname: ', pLoc.hostname);
5  }
6}

PlatformLocation 服务提供对 URL 各个部分的附加访问。有关如何使用 $location 替换的详细描述(用于更好地交织两个框架)能够在这里找到。此外,你如今能够找到延迟加载 AngularJS 的想法,它基于前面提到的动态 ECMAScript 导入。

结论

Angular团队再次表达了本身的观点:迁移到新的 Angular 版本很容易,而且不须要进行大的更改。使得使用 Google 的 SPA 框架更加温馨。若是旧版浏览器不受支持或不支持单独的 bundle 包,则差别加载会为进一步优化 bundles 包。 Web worker 支持代表愈来愈多的计算密集型任务开始进入浏览器。如今能够尝试用 Ivy 迈出第一步。

原文:https://jaxenter.com/whats-new-angular-8-159020.html

相关文章
相关标签/搜索