@NgModule
はAngularでモジュールを作成する際の宣言文のような役割を果たすデコレータです。@NgModule
を用いることで指定したクラスがモジュールであることを明示的に宣言します。
参考 Angularとは?
- Qモジュールとは?
- A
モジュールとは関連するコードの集まりのこと。Angularにおけるモジュールは、コンポーネント、サービス、ディレクティブ、パイプなど、アプリケーションを構成する部品をまとめる役割を担います。
// 必要なAngularのコアモジュールをインポート import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; // アプリケーションが使用するコンポーネントをインポート import { AppComponent } from './app.component'; @NgModule({ declarations: [ AppComponent // アプリケーションのコンポーネントを宣言 ], imports: [ BrowserModule // ブラウザで動作するアプリケーションに必要なモジュールをインポート ], providers: [], // サービスプロバイダー(ここでは空) bootstrap: [AppComponent] // アプリケーションのルートコンポーネントを指定 }) export class AppModule { }
このページでは、Angular初心者の方向けにそもそもモジュールとは何か?という初歩の初歩から解説し、@NgModule
の意味と基本的な使い方を1からわかりやすくサンプルコード付きで解説します。
Angularのモジュールとは?
Angularのモジュールは、レゴブロックのセットのようなものです。
レゴは1つひとつの小さなブロックを組み合わせて様々なものを組み立てていきますよね。たとえば、家を作る時には、窓のブロック、ドアのブロック、屋根のブロックなど、それぞれのパーツを組み合わせることで1つの家を作り上げることができます。レゴブロックに家を組み立てるためのブロックセットがあるように、Webページの一部分を作るために必要な「コンポーネント」や「サービス」などのパーツを1つにまとめたものとして、Angularのモジュールが存在します。
例えば、「プロフィールページ」というモジュールがあるとすると、このモジュールには「ユーザーの写真を表示するパーツ」「ユーザーの名前を表示するパーツ」「連絡先を表示するパーツ」などが含まれるかもしれません。これらのパーツを1つにまとめたものが「プロフィールページモジュール」です。
モジュールの必要性
大きなレゴの城を組み立てるとき、0から100までの全部を一度に組み立てようとすると大変です。(土台から天守閣までの一度に作成しようとすると、作業中に「いまは何をしていたっけ?」というように混乱してしまう・・・)
しかし、城の一部分ごとにセットを分けて、それぞれのセットを別々に組み立ててから、最後に全部をつなげるともっと簡単にできます。まずは、土台を作り、次に1階部分、2階部分として作成し、最後にそれぞれのブロックを連結させて作った方が簡単です。
Angularのモジュールも同じで、Webアプリケーションをいろいろなモジュール(セット)に分けることで、ひとつひとつをシンプルに作っていくことができます。そして、全部のモジュールが完成したら、それをつなげて一つの大きなウェブアプリケーションを完成させるようなイメージ。
このモジュールを作成するために利用するのが@NgModule
です。
Angular:@NgModuleデコレータ
@NgModule
はAngularのデコレータの一種で、指定したクラスをAngularモジュールとして識別します。@NgModule
は、モジュールのメタデータをAngularフレームワークに提供するために使用され、モジュールの振る舞いを定義します。
- Qモジュールのメタデータとは?
- A
メタデータには、モジュールに属するコンポーネント、インポートされる他のモジュール、提供するサービス、アプリケーションの起動時に最初にロードするコンポーネントなどが含まれます。
@NgModule
を使用することで、アプリケーションの構造をAngularに伝え、依存関係の注入、コンポーネントのスコープ、再利用可能な機能のグループ化などを実現します。
ひとまずここでは「モジュールはいろんな部品をまとめた1つの箱」のようなイメージを持てればOK。
言葉だけで説明されても、中々イメージは湧かないと思いますので、早速モジュールの作成方法~利用方法までをサンプルコード付きで解説していきます。
@NgModuleの構文ルール
@NgModule
デコレータは、クラス定義の直前に配置。デコレータは次のように使用します。
@NgModule({ // プロパティ: 値 }) export class MyModule {}
@NgModuleデコレータのプロパティ
プロパティ | 説明 |
---|---|
declarations | モジュール内で使用されるコンポーネント、ディレクティブ、パイプを宣言。これらはモジュール内でのみ参照可能。 |
imports | 現在のモジュールで必要とされる他のモジュールを指定。→インポートされたモジュールのコンポーネント、ディレクティブなどを使用できるようになる。 |
exports | 他のモジュールで使用できるようにするコンポーネント、ディレクティブ、パイプを指定。これらはdeclarations で宣言されたもののサブセット。 |
providers | モジュールで使用されるサービスのプロバイダーを指定。→サービスがモジュール内のすべてのコンポーネントで利用可能になります。 |
bootstrap | アプリケーションの起動時にインスタンス化されるルートコンポーネントを指定。このプロパティは主にルートモジュールで使用される。 |
schemas | テンプレートで使用されるカスタム要素や属性を許可するために使用。例えば、NO_ERRORS_SCHEMA やCUSTOM_ELEMENTS_SCHEMA があります。 |
id | モジュールのIDを指定します。これは通常、遅延ロードされるモジュールに使用されます。 |
これらのプロパティを使用して、Angularモジュールを定義し、アプリケーションの構造を整理することができます。
サンプルコード Angularモジュールの作成例
// 必要なAngularのコアモジュールをインポート import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; // アプリケーションが使用するコンポーネントをインポート import { AppComponent } from './app.component'; @NgModule({ declarations: [ AppComponent // アプリケーションのコンポーネントを宣言 ], imports: [ BrowserModule // ブラウザで動作するアプリケーションに必要なモジュールをインポート ], providers: [], // サービスプロバイダー(ここでは空) bootstrap: [AppComponent] // アプリケーションのルートコンポーネントを指定 }) export class AppModule { }
AppModule
はAngularのルートモジュールとして機能し、アプリケーションで最初にロードされるモジュールです。declarations
には、このモジュールが直接使用するAppComponent
が含まれています。imports
には、アプリケーションがブラウザで動作するために必要なBrowserModule
が含まれています。bootstrap
には、アプリケーションの起動時に最初にロードされるコンポーネントが指定されています。
モジュールの使用
ここからは、具体的な例を用いて実際にモジュールを定義する方法を見ていきましょう。
サンプルシナリオ
アプリケーションに「ユーザー管理機能」と「注文管理機能」があるとします。これらの機能をそれぞれ別のモジュールで管理することにしました。UserModule
とOrderModule
を作成し、それぞれに関連するコンポーネントやサービスをグループ化します。
ステップ 1: 機能モジュールの作成
UserModule
には、ユーザー一覧を表示するUserListComponent
とユーザーの詳細を表示するUserDetailComponent
が含めます。
// src/app/user/user.module.ts import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { UserListComponent } from './user-list.component'; import { UserDetailComponent } from './user-detail.component'; @NgModule({ declarations: [UserListComponent, UserDetailComponent], imports: [CommonModule], exports: [UserListComponent] // UserListComponentを外部に公開 }) export class UserModule {}
同様に、OrderModule
には注文一覧を表示するOrderListComponent
を含めます。
// src/app/order/order.module.ts import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { OrderListComponent } from './order-list.component'; @NgModule({ declarations: [OrderListComponent], imports: [CommonModule], exports: [OrderListComponent] // OrderListComponentを外部に公開 }) export class OrderModule {}
ステップ 2: モジュールの利用
AppModule
(ルートモジュール)でUserModule
とOrderModule
を利用することにします。これにより、アプリケーション全体でユーザー管理と注文管理の機能が使えるようになります。
// src/app/app.module.ts import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { UserModule } from './user/user.module'; // UserModuleをインポート import { OrderModule } from './order/order.module'; // OrderModuleをインポート @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, UserModule, // AppModuleにUserModuleを追加 OrderModule // AppModuleにOrderModuleを追加 ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
このように、Angularモジュールは「呼び出し」されるものではなく、アプリケーションの構造を定義し、コードを機能単位で整理するために「利用」されます。ルートモジュール(AppModule
)または他の機能モジュール内でモジュールをインポートすることにより、そのモジュールが提供する機能(コンポーネント、サービスなど)をアプリケーションの他の部分で使用できるようになります。