@NgModuleがなんなのかを知るにあたり、いくつか前提知識が必要となります。
前回はJavaScriptのモジュールについての勝手訳を書きました。
今回はAngular - JavaScript Modules vs. NgModulesの勝手訳です。

前段

JavaScriptとAngularは、コードを整理するのにそれぞれ異なったやり方でモジュールを使います。Angularはその両方に依っています。

JavaScriptモジュール

JavaScriptでは、モジュールはコードが書かれた個々のファイルです。

モジュールの中身を使わせたいときは、こんなコードを書きます。


export class AppComponent { ... }

そのモジュールを使いたいときは、こんなコードを書きます。


import { AppComponent } from './app.component'

NgModule

NgModuleは@NgModuleによって修飾されたクラスです。@NgModuleのなかのimports配列は、そのモジュールが使いたい他のNgModuleを示します。これはJavaScriptのモジュールとは違います。
@NgModuleがついたクラスはそれぞれ個別のファイルに保存されていますが、JavaScriptのモジュールのように個別のファイルがNgModuleであることを意味するわけではありません。@NgModuleとメタデータがあることでNgModuleになります。

Angular CLIコマンドによって生成されたファイルは、JavaScriptモジュールとNgModule両方になっています。

app.module.js

/*
これらはJavaScriptのインポートステートメントです。
Angularはこれらについて関知しません。
*/
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';

/*
@NgModule修飾子が、AngularにこのクラスがNgModuleであることを示します。
*/
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [     /* 他のNgModuleをインポートしています。 */
    BrowserModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

NgModuleクラスとJavaScriptモジュールの違いを並べるとこんなところです。

  • NgModuleは宣言可能なクラスにのみ束縛されます。宣言可能なクラスは、Angularコンパイラにとって、唯一重要なクラスです。
  • JavaScriptモジュールのようにメンバークラスをひとつの巨大なファイルにまとめるのではなく、@NgModule.declarationsリストにNgModuleクラスを列挙します。
  • NgModuleは、他からインポートしたか、自分自身である宣言可能なクラスのみをエクスポートします。それ以外のクラスを宣言したりエクスポートしたりはしません。
  • JavaScriptモジュールと異なり、NgModuleは@NgModule.providersリストにプロバイダを追加することにより、アプリケーション__全体__を拡張できます。