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裝飾器的服務。

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類型的值。

<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已棄用。

TestBed.get(ChangeDetectorRef) // returns any

TestBed.inject(ChangeDetectorRef) // returns ChangeDetectorRef

ViewChild中Static標誌的默認值

Angular 8中引入的另一項重大更改,是ViewChild需要static標誌。靜態屬性仍然存在,但使用假值時我們不再需要傳遞這個屬性。使用ng update更新到Angular 9後,遷移會移除所有位置使用的{ static: false }。

@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將負責這部分的遷移。

之前的代碼:

@NgModule({ ...}) export class MyModule {
 static forRoot(config: SomeConfig): ModuleWithProviders {
   return {
         ngModule: SomeModule,
         providers: [{ provide: SomeConfig, useValue: config }]
   };
 }
}

遷移後:

@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用於接受以下選項:
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屬性

之前:

"assetGroups": [
  {
    "name": "test",
    "resources": {
      "versionedFiles": [
        "/**/*.txt"
      ]
    }
  }
]

之後:

"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中指定以下選項:

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中,可以像下面的配置一樣簡化這裏的步驟。

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章