Angular: NgModule概要


前提


ドキュメント


JavaScriptモジュールとは

// node_modules/@angular/core/以下でexportされたComponentをインポート
import { Component } from '@angular/core'

以降の、NgModuleのインポートやエクスポート(imports, exports)とは違う。


NgModuleとは


ルートモジュールAppModule: src/app/app.module.ts

// AppModuleの初期状態
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

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

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

基本的に上記3点は削除せず、必要なものを配列に追加していく。


@NgModuleデコレータに渡すオブジェクト

@NgModule({
  declarations: 配列,
  imports: 配列,
  exports: 配列,
  providers: 配列,
})
export class FooModule { }

declarations配列

宣言クラス


imports配列とexports配列

あるNgModuleが他のNgModule(の宣言クラス)を利用できるようにする。

exports配列

imports配列


NgModule階層の例

  1. XxxModuleがX1Componentを宣言し、exports
@NgModule({
  declarations: [X1Component],
  exports: [X1Component]
})
export class XxxModule { }
  1. YyyModuleがXxxModuleをexports(再エクスポート)
@NgModule({
  exports: [XxxModule]
})
export class YyyModule { }
  1. AppModuleがYyyModuleをimports
@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    YyyModule,
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

providers配列

依存性の注入(Dependency Injection、DI)

例えばHTTPでどこかAPIにアクセスするコンポーネントの場合、通常、コンポーネントクラス自身でその機能を実装することはせず、別途サービスと呼ぶクラスを作り、そこで実装する。

そうしてサービスの利用側になったコンポーネントは、通常、サービスクラスのインスタンスを自らnew MyService()などと作ることはせず、Angularの依存性の注入システムを利用して、インジェクタに注入してもらう。

プロバイダ

インジェクタは注入前に下記のことを決定する必要があるが、この挙動を決めるのがプロバイダ。

一度作成したインスタンスをアプリのどこでも使い回すという基本的な使い方の場合、providers配列は触らない。


Angularが用意したNgModuleの例

ルートモジュール: AppModule(app.module.ts)

標準ライブラリ

インポートしても実際には使用しないクラスが多数発生し得るが、本番ビルドではツリーシェイキング(不要なもの削除)される。

いろんな場所で同じライブラリを複数回インポートしても、問題ない(BrowserModule除く)。


自作するNgModuleの例

フィーチャーモジュール

ルーティングモジュール

共有モジュール

サービス


事前ロード


遅延ロード

フィーチャーモジュールとその専用のルーティングモジュールがあるとき、次のような流れのインポートになる。

ルーティングの流れ(イメージ)は、

この場合のフィーチャーモジュールは、事前ロードには含まれず、そのルーティング(URLアクセス)の時にロードされる(別のJavaScriptファイルとして)。


NgModule作成コマンド: ng generate module

新NgModule名を指定して、オプションを続ける。

# XxxModuleを作成し、AppModuleに所属させる場合
ng generate module xxx --project プロジェクト名 --module app

デフォルトでCommonModuleimports済み。

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

@NgModule({
  declarations: [],
  imports: [
    CommonModule
  ]
})
export class XxxModule { }