standalone component は Angular 学習の複雑さを上げている要因の NgModule の必要性を減らすことを目的としている。 その standalone component が v14 で開発者プレビューとして使えるようになったので、試してみる。
なお、開発者プレビューであるため後のアップデートで変更される可能性がある。
standalone component の作り方
まずは Angular v14 を使ったアプリケーションを用意する。新しいコンポーネントで作る場合は以下のように --standalone
フラグを付けるだけでよい。
$ yarn ng g c top-bar --standalone
すると以下のようなコンポーネントが作成される。
import { Component, OnInit } from '@angular/core'; import { CommonModule } from '@angular/common'; @Component({ selector: 'app-top-bar', standalone: true, imports: [CommonModule], templateUrl: './top-bar.component.html', styleUrls: ['./top-bar.component.scss'] }) export class TopBarComponent implements OnInit { constructor() { } ngOnInit(): void { } }
注目すべき点は 2 つありは 1 つは standalone: true
である。対象のコンポーネントが standalone component かどうかはこのフラグが決めており、既存のコンポーネントを standalone component にするときも standalone: true
を追加すれば良い。
2 つ目は imports
である。NgModule を使わないので依存関係は自分で解決する必要がある。従来の NgModule の他に新たに作った別の standalone component も指定できる。
angular.json でデフォルトのフラグを変更
新規につくるコンポーネントは standalone component を中心に作っていくと決めた場合は angular.json でデフォルトの設定を変えることもできる。 設定は以下の通り。
"projectType": "application", "schematics": { "@schematics/angular:component": { "standalone": true }, ... } ... }
ルートコンポーネントを standalone component にしてブートストラップする
ルートコンポーネントである AppComponent も standalone component にすることができる。
まずは AppComponent に standalone: true
を追加する。上でも触れたがコンポーネント自体はこれで standalone component になる。
次に修正が必要なのは main.ts である。従来は NgModule が起点になっていたため以下のようにアプリケーションを起動していた。
platformBrowserDynamic().bootstrapModule(AppModule) .catch(err => console.error(err));
対象が standalone component になることで、専用のブートストラップ API を使う必要があるので下記のように書き換える必要がある。
bootstrapApplication(AppComponent);
AppModule で解決していた依存関係は直接 AppComponent の imports に書くことができる。 しかし RouterModule のように一部の既存 module は NgModule に依存しているものがあるので、それらは standalone component にではなく以下のようにブートストラップ時に指定しなければならない。
bootstrapApplication(AppComponent, { providers: [importProvidersFrom(AppRoutingModule)], });
これでルートコンポーネントも standalone component にできる。
まとめ
standalone component の作り方と既存のコンポーネントの standalone 化を試したが、どちらもスムーズに確認できた。 今回は新規アプリケーションに対して試したが、既存のアプリケーションにも部分的に適用できるのでまた色々と試したみたい。