← NestJS コース
33. 動的モジュール — forRoot パターン
ここまで使ってきた ConfigModule.forRoot(...) や TypeOrmModule.forRoot(...) は、動的モジュールという仕組みです。通常のモジュールは @Module({...}) で構成が固定ですが、動的モジュールは forRoot(options) という静的メソッドを持ち、呼び出し側から設定を受け取って、その場で providers を組み立てた DynamicModule オブジェクト({ module, providers, exports }) を返します。
実務での慣習として、アプリ全体で一度だけ設定する全体設定には forRoot、機能(リポジトリなど)ごとに繰り返し登録するものには forFeature、汎用ライブラリには register という名前を使い分けます。自作の共有ライブラリ(社内の認証モジュールやロガーモジュールなど)を「設定を渡して使ってもらう」形で配るときに、このパターンで作ります。受け取った options は useValue でトークンに載せて、モジュール内のサービスに注入できるようにするのが定番です。
つまずきポイントは、forRoot を呼ぶ場所です。forRoot は基本的にルートモジュール(AppModule)で一度だけ呼び、各機能モジュールでは設定を渡さない forFeature を使います。同じ全体設定を複数箇所で forRoot してしまうと、設定が重複して予期しない動作になりがちです。
サンプルコード(フレームワーク環境が必要なため表示のみ)
import { Module, DynamicModule } from "@nestjs/common";
export type StorageOptions = { bucket: string };
@Module({})
export class StorageModule {
// forRoot: 設定を受け取り、その場でモジュール構成を組み立てて返す
static forRoot(options: StorageOptions): DynamicModule {
return {
module: StorageModule,
providers: [
// 渡された設定をトークンに載せて注入可能にする
{ provide: "STORAGE_OPTIONS", useValue: options },
StorageService,
],
exports: [StorageService],
};
}
}
// 利用側(AppModule)— 設定を渡して一度だけ登録する
@Module({
imports: [StorageModule.forRoot({ bucket: "my-app" })],
})
export class AppModule {}
サンプルコードで身につける(5本) →
学んだ概念を、素朴な例から実務寄りの例まで5つの具体例で確認します。
公式ドキュメントで詳しく ↗