首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Angular 9即将发布:改进Ivy编译和渲染管道

你知道吗?Angular 9 就要来啦!Angular 是基于 TypeScript 的 Web 应用程序框架,Angular 9 的一系列更新将为开发者们带来不小的影响。本文将主要从最新功能、重大更改、Angular 组件等方面对 Angular 9 的相关动态进行详解。

Angular 9 RC 版已经发布了,这对 Angular 开发人员来说真是激动人心的时刻——我针对的不是 Angular 9 RC 的发布,我说的是 Ivy,Ivy 现在是 Angular 中的默认渲染引擎。

相信我,如果你还没觉得有多兴奋,请看看Mathias Raacke的推文:一个Hello World应用才有7KB大小!

下面我们就来研究一下,看看除了Ivy还有哪些东西。

新功能

添加对未装饰类的迁移支持

对指令和组件来说,直到Angular 8时装饰器对基类都是可选的。这适用于未使用@Injectable装饰器的服务。

代码语言:javascript
复制
export class BasePlain {
  constructor(private vcr: ViewContainerRef) {}
}

@Directive({selector: '[blah]'})
export class DerivedDir extends BasePlain {}

引擎变成Ivy后这种类也需要装饰器。为了处理这种情况,使用ng update迁移时装饰器将作为迁移的一部分添加进来。请阅读此处内容以获取详情,有少数情况是不会被照顾到的。

FormControlName接受Number作为输入

下面的代码你可能已经用过很多次了,但是我们从来没有考虑过[formControlName]=“i”的工作机制;因为它接受字符串类型的值,所以没有fullTemplateTypeCheck也可以。但是在Ivy中这样做会失败。为了确保下面的语法仍然有效,formControlName可以接受string | number类型的值。

代码语言:javascript
复制
<div formArrayName="tags">
  <div *ngFor="let tag of tagsArray.controls; index as i">
    <input [formControlName]="i">
  </div>
</div>

用TestBed.inject替换TestBed.get

在Angular 8中有一项重大更改,TestBed.get不再接受字符串值;现在团队决定回滚更改,因为它影响到了更大的应用程序基础部分。现在我们有了类型安全的版本TestBed.inject,TestBed.get已弃用。

代码语言:javascript
复制
TestBed.get(ChangeDetectorRef) // returns any

TestBed.inject(ChangeDetectorRef) // returns ChangeDetectorRef

ViewChild中Static标志的默认值

Angular 8中引入的另一项重大更改,是ViewChild需要static标志。静态属性仍然存在,但使用假值时我们不再需要传递这个属性。使用ng update更新到Angular 9后,迁移会移除所有位置使用的{ static: false }。

代码语言:javascript
复制
@ViewChild(ChildDirective) child: ChildDirective;
@ViewChild(ChildDirective, { static: false }) child: ChildDirective; // similar to above code

ng-add支持@angular/localize

要使用@angular/localize,我们现在可以运行ng add @angular/localize,这条命令会安装软件包并将必要的导入添加到polyfills中,这也是它工作时需要的。

针对Template的FullTemplateTypeCheck

在使用Angular时常常会遇到一个问题:“为什么不严格检查模板的类型”。这是之前的情况,但是现在对于*ngIf、*ngFor这样的指令,甚至是管道都会是严格的。有3种模式可用于检查模板的类型:

  • 基本模式:设置fullTemplateTypeCheck: false来启用;
  • 完全模式:设置fullTemplateTypeCheck: true来启用;
  • 严格模式:设置fullTemplateTypeCheck: true和strictTemplates: true来启用。

更多详情请参阅这篇文档

TypeScript 3.6支持

新版Angular现在需要Typescript 3.6版本。下面是Lars Gyrup Brink Nielsen总结的Angular版本和对应的TypeScript版本支持。

Angular CLI、Anuglar、Node.js和TypeScript兼容性列表

对ModuleWithProviders的泛型支持

如果你是Angular库的所有者,那么你很可能已经用过Angular 9中的ModuleWithProviders了。现在必须使用泛型ModuleWithProviders类型来指示Angular模块类型。

新版已经添加了迁移原理图(Schematic),因此ng update将负责这部分的迁移。

之前的代码:

代码语言:javascript
复制
@NgModule({ ...}) export class MyModule {
 static forRoot(config: SomeConfig): ModuleWithProviders {
   return {
         ngModule: SomeModule,
         providers: [{ provide: SomeConfig, useValue: config }]
   };
 }
}

迁移后:

代码语言:javascript
复制
@NgModule({ ...})
export class MyModule {
  static forRoot(config: SomeConfig): ModuleWithProviders<SomeModule>
{
   return {
         ngModule: SomeModule,
         providers: [{ provide: SomeConfig, useValue: config }]
   };
 }
}

将原理图应用于库

ng update负责所有代码的迁移,但不适用于Angular库。在Angular 9中,ng update会将所有迁移原理图也应用于库项目。这对Angular库的作者来说是很重要的,可以让你的代码与最新更改保持同步。

不再需要entryComponents

如果你使用过Angular中的popup,则必须使用这个属性。有了它,你才能在动态加载组件后无需在模板中引用它。现在改用Ivy后就用不着它了。

重大更改

移除tslib依赖项

Angular现在不再依赖tslib。在早期版本的Angular中它是必需的,并且是依赖项的一部分。如果你不用Angular CLI,则可能需要安装这个包。

Forms

  • ngForm:以前</ ngForm>是有效的选择器,现在需要改用</ ng-form>。
  • NgFormSelectorWarning:在Angular 6中已弃用,现在已移除。此指令的目的是在使用已弃用的ngForm选择器时显示警告。
  • FormsModule.withConfig:FormsModule.withConfig已被移除。我们需要直接使用FormsModule,之前withConfig用于接受以下选项:
代码语言:javascript
复制
opts: { warnOnDeprecatedNgFormSelector?: "never" | "once" | "always"; }
  • 弃用类型RenderComponentType已被移除。请改用RendererType2。
  • 弃用类型RootRenderer已被移除。请改用RendererFactory2。

Angular Translation

  • Translations(通过loadTranslations()函数加载)现在必须使用MessageId作为Translation键,替代之前的SourceMessage字符串。
  • 要将$localize函数附加到全局范围,请从@angular/localize/init导入。以前这里是@angular/localize。
  • 要访问loadTranslations()和clearTranslations()函数,请从@angular/localize导入。以前这里是@angular/localize/run_time。

Service Worker

在ngsw-config.json中移除了versionedFiles属性

之前:

代码语言:javascript
复制
"assetGroups": [
  {
    "name": "test",
    "resources": {
      "versionedFiles": [
        "/**/*.txt"
      ]
    }
  }
]

之后:

代码语言:javascript
复制
"assetGroups": [
  {
    "name": "test",
    "resources": {
      "files": [
        "/**/*.txt"
      ]
    }
  }
]

Angular Bazel

  • @angular/bazel ng_setup_workspace()已经用不着了,并且已被移除。Angular会假设你将在WORKSPACE文件中获取rules_nodejs,并且这里没有其他依赖项。只需移除对此函数的任何调用和对应的load语句。
  • 如果你从@angular/bazel使用protractor_web_test_suite,现在要切换到@bazel/protractor包上。

弃用

  • TestBed.get函数已弃用,建议使用类型安全的TestBed.inject。

完整指南请参阅官方文档。本文没有涉及Ivy的介绍内容,因为这是一个非常大的主题,我们将很快写一篇博文来介绍Ivy的所有功能。

Angular CLI

支持验证CLI版本

新增检查可以验证所安装的CLI是否为最新发布的版本。如果不是最新版,那么在运行ng update时将安装最新版本,作为临时包来运行迁移。

支持混合多种配置

之前我们使用ng build时可以使用–configuration来传递配置,一个问题是,如果我想覆盖某些配置,我们必须复制整个配置并创建一个新条目才能使用它。

现在可以使用ng build --configuration=prod,testing这样的写法,这样在testing配置中我们就可以只传递需要覆盖的配置。

指定ng-add的选项

另一项更新针对Angular库的作者,你可以使用ng add来指定是否应将包添加到依赖项。

你可以在package.json中指定以下选项:

代码语言:javascript
复制
ng-add : { 
     "save": false | true | 'dependencies' | 'devDependencies'
}

组件原理图的类型选项

目前来说,当我们使用ng gc user时,它将使用组件类UserComponent生成一个文件,其类型选项可让你定义要创建的组件类型;例如ng gc user --type=“dialog”将创建一个组件,其类名称为UserDialog。

生成拦截器的原理图支持

目前来说添加拦截器都是手动的。在Angular 9中,我们将能够使用ng g i custom创建CustomInterceptor类。

app-shell原理图更改

为了生成app-shell,我们必须传递–clientProject;它现在是可选的。如果没有提供,它将考虑默认项目。

生成原理图时跳过测试

如果我们使用–minimal=true创建应用程序,它将跳过端到端和单元测试配置。但当我们使用ng g生成component/pipe/service时,它会添加一个spec.ts文件。从Angular CLI 9开始这个问题已经解决了。

自动发现multiSelect schema prompt

现在要创建一个可以有multiSelect的prompt,我们必须提供其他许多选项。在Angular 9中,可以像下面的配置一样简化这里的步骤。

代码语言:javascript
复制
test: {
  type: 'array',
  'x-prompt': {
    'type': 'list',
    'multiselect': false,
    'items': [
      {
        'value': 'one',
        'label': 'one'
      },
      {
        'value': 'two',
        'label': 'two'
      },
    ],
    'message': 'test-message',
  },
}

支持提供npmrc文件路径

npm中提供了NPM_CONFIG_USERCONFIG和NPM_CONFIG_GLOBALCONFIG变量。当提供这些变量时,Angular CLI会首选它们而非全局.npmrc文件。请参阅npm文档以获取更多细节。

重大更改

  • 使用CLI时会移除styleext和spec选项,而应使用style和skipTests选项替代。

Angular组件

新的Clipboard模块

有一个新的剪贴板组件可用,它是@angular/cdk系列的一部分。

想要了解更多实现细节,请阅读Tim Deschryver的博客文章

hammerjs现在是可选的

在早期版本中需要hammerjs来添加手势支持。它现在是可选的,并且内部使用的所有实现都已移除,你可以使用@angular/platform-b​​rowser中的HammerModule。

针对谷歌地图的新包

@angular/google-maps包现已发布,所以集成谷歌地图不再是一项艰巨的任务了。这个包已经在多种设备上进行了测试。你可以参考Tim Deschryver的博客文章了解实现细节。

重大更改

  • 组件不再可以通过@angular/material导入。现在要使用单独的辅助入口点,例如@angular/material/button。
  • MAT_CHECKBOX_CLICK_ACTION已弃用,请使用MAT_CHECKBOX_DEFAULT_OPTIONS代替。

总结

终于看到Ivy更加稳定并且可以用于生产了,我感到非常兴奋,相信你也很会很激动。Angular CLI新增了许多很棒的功能,提升了我们的工作效率。很高兴看到Angular Material中添加了一些很棒的组件,例如地图和剪贴板。相信我,现在有了Ivy,我们可以对未来抱有更大的期待,因此Angular无疑会迎来激动人心的时刻,你也应该为此感到振奋。

作者介绍: Santosh Yadav拥有10多年的经验,他是Angular和NgRx的开源贡献者,并且是AngularInDepth和DotNetTricks的作者。

原文链接https://blog.angularindepth.com/exciting-time-ahead-be-ready-for-angular-9-b3dbb4078c47

  • 发表于:
  • 本文为 InfoQ 中文站特供稿件
  • 首发地址https://www.infoq.cn/article/8dhfBXLJrujtwOwmWP6Z
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券