NestJS における global モジュールについて

Published: 2023/8/12


NestJS には global モジュールと呼ばれる仕組みがある。 あらゆる箇所で利用したいモジュールは、 global モジュールとして登録しておくことで、個別のモジュールにていちいち import の対象に指定する必要がなくなる。

使い方の TL; DR

  1. モジュールの定義に対して、 @Global を付与する
  2. ルートモジュール(一番上の main.ts にて NestFactory.create の引数に与えるモジュール)にて import する
// PrismaService を global 化する例
import { Global, Module } from "@nestjs/common";
import { PrismaService } from "./prisma.service";

@Global()
@Module({
  providers: [PrismaService],
  exports: [PrismaService],
})
export class PrismaModule {}
// ルートモジュール(src/root.module.ts)の例
import { Module } from "@nestjs/common";
import { ConfigModule } from "@nestjs/config";
import { PrismaModule } from "./db/prisma.module";
import { UserModule } from "./user/index.module";

@Module({
  imports: [
    UserModule,
    // 共通系のモジュール
    PrismaModule,
    ConfigModule.forRoot(),
  ]
})
export class RootModule {}

解説

DI という観点で見たとき、 NestJS の @Module 宣言には以下の効用がある。

  • imports を指定することにより、他のモジュールで export されたクラスたちを、その export してたモジュールを利用して DI する。
  • providers, controllers などに指定された対象のクラスは、このモジュールのコンテキストにて DI される。
    • import したクラスたちと、同じモジュールの providers, controllers が DI と対象として利用可能になる。
  • exports として、他のモジュールがこのモジュールを import した際に、どのクラスが他のモジュールにて import 可能になるのかを指定する。
    • カプセル化のため。

@Global を付与したモジュールは、そこで export しているモジュールが、他のモジュールにおいて、明示的なモジュールの import なしに、利用できるようにする。

参考資料の通り、ルートモジュールから global module を import すると期待通りに動作するのは確認した。 一方で、モジュールの import 木構造のどこで import されたとしても問題なく動くのかどうかは、分かっていない。 おそらくはそういう振舞いになっていそうではあるが。

参考

ルートモジュールにて global module は import したら良い、と示している記事。

However, we can register the global module in the root module. By doing so, we have no need to import it anywhere else.


Tags: nestjs

関連記事