NestJSの基本的な構成 ~Modules編~

## これはなに？

前回までの記事と同様にModulesの理解を深めようと思ったので記事にしました。

この記事が新たにNestJSに入門する方の手助けになれば幸いです。

前回までの記事はこちら

https://qiita.com/mu-suke08/items/67eef21369eb6edc0fcc

https://qiita.com/mu-suke08/items/7a97819e273f76a1bb1c

## この記事のゴール

以下の理解が得られることをゴールとします

- Modulesの役割が理解できること

## Modulesってなに？

> We want to emphasize that modules are **strongly** recommended as an effective way to organize your components.
引用: [https://docs.nestjs.com/modules](https://docs.nestjs.com/modules)
> 

上記はNestJSの公式ドキュメントから引用したものです。

簡単に訳すと以下になります。

> コンポーネントをまとめるための手段としてモジュールを利用することを強くおすすめしています。



つまりModulesの役割とは、今まで説明してきた**ControllerやProviderをまとめてモジュールという一つの単位にすること**です。

今回も文章だけだとわかりづらいのコードを用いて説明していきます。


## Modulesがない場合

まずはModulesがない場合を見てみます。

### 1. cat, dogのController, Providerを作成する

例によって以下のコマンドでcat, dogのControllerとProviderを作成していきます。

```bash
$ nest g co cat // catのProvider作成
$ nest g s cat  // catのController作成
$ nest g co dog // dogのController作成
$ nest g s dog  // dogのProvider作成
```

app.module.tsを見てみましょう

```tsx
import { Module } from '@nestjs/common'
import { AppController } from './app.controller'
import { AppService } from './app.service'
import { CatController } from './cat/cat.controller'
import { CatService } from './cat/cat.service'
import { DogController } from './dog/dog.controller'
import { DogService } from './dog/dog.service'

@Module({
  imports: [],
  controllers: [AppController, CatController, DogController],
  providers: [AppService, CatService, DogService],
})
export class AppModule {}
```

catとdogそれぞれのController, Providerが呼ばれて登録されています。

ここまではまだ問題ないと思います。

しかしこのControllerやProviderがさらに増えたらどうでしょうか？

### 2. lion, tiger, wolfのController, Providerを作成する

仕様追加によりlion, tiger, wolfを追加することになりました。
先ほどと同様に登録していきます。

するとapp.moduleは以下のようになります。

```tsx
import { Module } from '@nestjs/common'
import { AppController } from './app.controller'
import { AppService } from './app.service'
import { CatController } from './cat/cat.controller'
import { CatService } from './cat/cat.service'
import { DogController } from './dog/dog.controller'
import { DogService } from './dog/dog.service'
import { LionService } from './lion/lion.service'
import { TigerService } from './tiger/tiger.service'
import { WolfService } from './wolf/wolf.service'
import { LionController } from './lion/lion.controller'
import { TigerController } from './tiger/tiger.controller'
import { WolfController } from './wolf/wolf.controller'

@Module({
  imports: [],
  controllers: [
    AppController,
    CatController,
    DogController,
    LionController,
    TigerController,
    WolfController,
  ],
  providers: [
    AppService,
    CatService,
    DogService,
    LionService,
    TigerService,
    WolfService,
  ],
})
export class AppModule {}
```

お分かりでしょうか？

見て分かる通りcontrollersとproviders、それをimportしている部分の記述量がかなり多くなっています。

これが10, 20と増えていくと…。

想像がつきますよね？

コード量がとてつもないことになり、app.moduleがカオスなことになります。

## Modulesがある場合

それを防ぐためにmodulesが存在します。

では、cat, dogそれぞれにmodulesを作ってみましょう

```tsx
import { Module } from '@nestjs/common'
import { AppController } from './app.controller'
import { AppService } from './app.service'
import { CatModule } from './cat/cat.module'
import { DogModule } from './dog/dog.module'

@Module({
  imports: [CatModule, DogModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

かなりスッキリしました。

上の例のようにルートモジュールでのimportの肥大化を防ぐだったりコンポーネントを整理する目的で利用されます。

| Modules利用前 | Modules利用後 |
| --- | --- |
| ![スクリーンショット 2022-02-19 2.21.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316760/8562ae7c-106f-cb6b-34d0-956d808ca230.png) | ![スクリーンショット 2022-02-19 2.21.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316760/70148304-08ed-a35a-5c85-a74667055a4e.png) |

## まとめ

- モジュールという単位にまとめるもの
- それによってコンポーネントが整理される

## 余談

1月からNestJSに入門してはや1ヶ月半が経ちました。

「全く分からない」から「分からないところが分かる」という状況までくることができました。

引き続き業務で使いながら何かしらアウトプットをしていこうと思います。

ではまた！

## 参考記事

https://docs.nestjs.com/controllers

https://zenn.dev/kisihara_c/books/nest-officialdoc-jp/viewer/overview-controllers