Exciting Times Ahead — Be Ready For Angular 9 を翻訳しました

本記事は、Angular In Depth のエントリ、

Exciting Times Ahead — Be Ready For Angular 9
( https://blog.angularindepth.com/exciting-time-ahead-be-ready-for-angular-9-b3dbb4078c47 )

を原著者 Santosh Yadav氏の許可を得て翻訳したものです。
Angular 9 のRC版について、注目すべき機能や、これまでとの変更点、破壊的変更に対する対応などがまとめられています。


エキサイティングな時が目前に - Angular9に備える(Exciting Times Ahead — Be Ready For Angular 9)

Santosh Yadav
投稿日:2019年11月5日

BeReadyForAngular9_img01.jpg

Angular9のRC版が公開されました。Angular開発者にとってはとてもエキサイティングな時です。いや、Angular9 RCリリースがあるからそう言っているわけではありません。Ivy があるからです。Ivy がAngularのデフォルトのレンダリングエンジンになるのです。

インドの大きなAngularカンファレンスが2020年2月29日に控えており、我々の中にAngularのコアチームから参加するスピーカーがいます。2019年のカンファレンスは大成功で、我々は、みなさんが今年と同じように2020年も参加してくれることを望んでいます。チケットは11月7日の午後から販売されます。詳細は ng-india の Webサイトにアクセスしてください。

https://twitter.com/esosanderelias/status/1190106464901378048

私を信じてください。もし、あなたがまだワクワクしないなら、Mathias Raacke からのツイートを見てください。7KB の Hello Worldのアプリです

https://twitter.com/oocx/status/1190672446711570433

ではこれから、Ivyとは何が違うのかを見ていきましょう。

新機能

デコレーターが使用されてないクラス用に移行サポートを追加

Angular8まで、デコレーターはディレクティブやコンポーネントの基底クラスに対するオプションでした。 これは @Injectableデコレーターが使用されていないサービスに適用されています。

    export class BasePlain {
        constructor(private vcr: ViewContainerRef) {}
    }

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

Ivyでは、このようなクラスにデコレーターが必要になります。本ケースへの対処として、あなたが ng update を使用してAngular9への移行を行った場合、デコレーターはマイグレーションの一部として追加されます。

FormControlNameで数字の入力が可能に

あなたは以下のコードを何回か使用したことがあるかもしれませんが、我々は、[formControlName]="i" がstring型の値をとることで、どのように振る舞うかということを考えていませんでした。これまでは fullTemplateTypeCheck がなかったので上手く動きましたが Ivyでは失敗します。 string | number型の値が入力可能な formControlName で、以下の構文が引き続き動作します。

    <div formArrayName="tags">
    <div *ngFor="let tag of tagsArray.controls; index as i">
        <input [formControlName]="i">
    </div>
    </div>

TestBed.get を TestBed.inject へ置き換える

Angular8 では、TestBed.get が stringの値を受け入れられなくなるという破壊的変更があり、チームはより大きなアプリケーションベースに影響していた変更をロールバックすることに決めました。 今はタイプセーフバージョンの TestBed.inject があるので、TestBed.get は非推奨となります。

    TestBed.get(ChangeDetectorRef) // returns any

    TestBed.inject(ChangeDetectorRef) // returns ChangeDetectorRef

ViewChild内のStaticフラグ用のデフォルト値

Angular8に取り込まれた他の破壊的変更は ViewChildstaticフラグが必須であることです。 静的プロパティはまだありますが デフォルトでfalseの値を使用するため、このプロパティを渡す必要がなくなりました。ng updateを使用してAngular9に更新した場合、マイグレーションは { static: false } の使用箇所を削除します。

    @ViewChild(ChildDirective) child: ChildDirective;

    @ViewChild(ChildDirective, { static: false }) child: ChildDirective; // similar to above code

@angular/localize のための ng-add サポート

@angular/localize を使用する場合、ng add @angular/localize を実行してパッケージをインストールし、ポリフィルに必要なインポートを追加することができます。これは @angular/localize を動作させるために必須となります。

テンプレートのための FullTemplateTypeCheck

Angularの動作中、常に発生する問題のひとつは「なぜテンプレートが厳密に型チェックされないのか」です。これは少し前までは起こるケースでしたが、今回では *ngIf*ngForのようなディレクティブや、パイプまで厳格にチェックされるようになります。テンプレートの型チェックには3つのモードがあります。

  • Basic モード : fullTemplateTypeCheck: false が有効なセット

  • Full モード : fullTemplateTypeCheck: true が有効なセット

  • Strict モード : fullTemplateTypeCheck: truestrictTemplates: true が有効なセット

詳細についてはこちらのドキュメントを参照してください。

Typescript 3.6 のサポート

Typescript version 3.6 が必須となりました。 Lars Gyrup Brink Nielsen の gistに、それぞれの Angularのバージョンがサポートしている Typescriptのバージョンが記載されています。

TypeScriptCompatibilityTable.png

Angular CLI、Angular、Node.js と TypeScript の互換性一覧
こちらをクリックすると新しいタブで開きます。

ModuleWithProviders のジェネリックサポート

もしあなたが Angularライブラリのオーナーであるなら、Angular9で ModuleWithProviders を使う機会が増えます。今回はジェネリック ModuleWithProviders<T> の使用が必須となります。typeは 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 }]
        };
      }
    }

ライブラリへの Schematics 適用

ng updateは全てのコードのマイグレーションを担いますが、Angularのライブラリには適用されませんでした。Angular9では、ng update が、すべてのマイグレーション Schematics をライブラリプロジェクトへ適用します。 もし、あなたがAngularライブラリの作者であり、あなたのコードを最新の変更に同期する場合、これは重要になります。

もう entryComponents はありません

もし、あなたがAngularのポップアップを使わなければならない場合、このプロパティを使っていることでしょう。それはテンプレートから動的に参照外のコンポーネントをロードするのに必須でした。Ivyではもう必須ではありません。

破壊的変更

tslibへの依存が削除されました

今回、Angularはtslibに依存していません。Angularの以前のバージョンでは必須であり、部分的に依存していました。ただし Angular CLI を使っていない場合は、このパッケージをインストールする必要があります。

Forms

  • ngForm:
    これまで <ngForm></ngForm> は有効なセレクターでした。もしこれを使っている場合は <ng-form></ng-form> へ移行してください。

  • NgFromSelectorWarning:
    これは Angular6で非推奨になっています。今回、非推奨のngFormセレクターが使われた際に警告を表示する目的である本ディレクティブは削除されます。

  • FormsModule.withConfig:
    FormsModule.withConfig は削除されました。我々は直接 FormsModule を使う必要があり、withConfig は以下のオプションを取得するために使われます。
    opts: { warnOnDeprecatedNgFormSelector?: "never" | "once" | "always"; }

  • 非推奨の型 RenderComponentType は削除されました。代わりに RendererType2 を使用してください。

  • 非推奨の型 RootRenderer は削除されました。代わりに RendererFactory2 を使用してください。

Angular Translation

  • Translations (loadTranslations() 関数を介してロードされる) は、以前の SourceMessage 文字列でなく、MessageIdをキーとして使う必要があります。

  • $localize 関数をグローバススコープにアタッチするため、以前は @angular/localize からインポートしていましたが、@angular/localize/init に変更されます。

  • loadTranslations()clearTranslations() 関数にアクセスするため、以前は @angular/localize/run_time からインポートしていましたが、@angular/localize に変更されます。

サービスワーカー

versionedFiles プロパティは ngsw-config.json から削除されました。

Angular9 以前

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

Angular9 以降

    "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.inject が採用されたので TestBed.get関数は非推奨になります。

完全なガイドは Official docs を参照してください。ただ、Ivyに関するはトピックはとても大きいため、何もカバーできていません。我々はIvyのすべての機能をカバーするブログ記事をまもなく執筆します。

Angular CLI

CLIバージョンの検証をサポート

インストールされているCLIバージョンが最新の公開バージョンかを検証する Check が追加されます。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'
    }

コンポーネント Schematic の typeオプション

今のところ ng g c userを使うと、UserComponent コンポーネントクラス のファイルが生成されます。この時、typeオプションを使用すると、作成するコンポーネントのタイプを定義することが可能になります。 例えば ng g c user --type="dialog" とすると、UserDialogというクラス名のコンポーネントが作成されます。

インターセプタ―を生成する Schematics のサポート

今までインターセプタ―の追加は手動で行われていましたが、Angular9では ng g i custom を使うことで CustomInterceptor クラスを作成することができます。

app-shell Schematic の変更

app-shell の生成で --clientProject を渡す必要がありましたが、今回からオプションになります。渡されない場合は、代わりにデフォルトのプロジェクトが配慮されます。

Schematics 生成中のテストのスキップ

--minimal=true によってアプリケーションを作成していた場合、e2eとユニットテストの設定がスキップされます。しかし ng g を使用して component/pipe/service を生成すると spec.tsファイルが追加されます。これは Angular CLI 9 から適用されます。

multiSelectスキーマ プロンプトの自動選択

プロンプトを作成する時、multiSelectを使うために他の多くのオプションを設定する必要があります。Angular9 では、以下の設定のように簡略化することができます。

    test: {
      type: 'array',
      'x-prompt': {
        'type': 'list',
        'multiselect': false,
        'items': [
          {
            'value': 'one',
            'label': 'one'
          },
          {
            'value': 'two',
            'label': 'two'
          },
        ],
        'message': 'test-message',
      },
    }

npmrc ファイルのパスを提供するためのサポート

Angular CLI が グローバルな .npmrcファイルより NPM_CONFIG_USERCONFIGNPM_CONFIG_GLOBALCONFIG 変数を優先するという条件下で、これらの変数が npmで使用可能となります。 詳細は npm docs を参照してください。

破壊的変更

  • CLIを使用すると、styleextspec オプションは削除されます。代わりに styleskipTests オプションを使用してください。

Angular コンポーネント

新しいクリップボードモジュール

@angular/cdk の一部である、新しいクリップボードのコンポーネントが利用可能です。

実装方法について詳細を知りたい場合は、 Tim Deschryver 氏のブログから、以下の記事を読んでください。

Use the new Angular Clipboard CDK to interact with the clipboard

Use the new Angular Clipboard CDK to interact with the clipboard
The new Material release brings us a new Clipboard CDK module, let’s explore the CDK with some examples.
blog.angularindepth.com

hammerjs はオプションになりました

以前のバージョンの hammerjs ではジェスチャーのサポート追加は必須でした。今回からはオプションであり、内部で使用されるすべての実装が削除されています。ユーザーは @angular/platform-browser から HammerModule を使うことができます。

Googleマップ の新しいパッケージ

@angular/google-maps パッケージが今回から利用可能になりました。Googleマップの統合は常に困難なタスクでしたが、もう違います。 このパッケージは既に複数のデバイスでテストされています。 実装方法については、Tim Deschryver 氏のブログ記事を参照してください。

Google Maps is now an Angular component

Google Maps is now an Angular component
The new Angular Component release introduces the second official @angular/component component, a Google Maps component.
blog.angularindepth.com

破壊的変更

コンポーネントは @angular/material を介してインポートできなくなりました。@angular/material/button のような、個々のセカンダリエントリポイントを使用してください。

  • MAT_CHECKBOX_CLICK_ACTION は非推奨です。MAT_CHECKBOX_DEFAULT_OPTIONS を使用してください。

まとめ

いよいよ、より安定しており、製品として使用する準備ができている Ivy が見られることに私は本当にワクワクしています。あなたも同様にワクワクさせられると思います。

Angular CLI には、さらに生産性を高めるため、いくつもの素晴らしい機能が追加されました。Angular Material にマップやクリップボードのような素晴らしいコンポーネントが追加されるのを見るのは喜ばしいことです。

そして今回 Ivy が登場します。信じてください、将来はもっと期待できます。Angularによるエキサイティングな時は確実にやってきます。あなたも同じように興奮させられるはずです。


元記事の著者について

Santosh Yadav

Santosh は Angular と NgRx のオープンソース コントリビューター、AngularInDepth と DotNetTricks のライターを 10年以上経験しています。
https://medium.com/@santosh.yadav198613

Angular In Depth

高度な Angular のコンセプトを解説している所です。
https://medium.com/angular-in-depth