Dynamic modules
Dynamic modules
๋ชจ๋ ์ฑํฐ๋ Nest ๋ชจ๋์ ๊ธฐ๋ณธ ์ฌํญ์ ๋ค๋ฃจ๊ณ ๋์  ๋ชจ๋์ ๋ํ ๊ฐ๋ตํ ์๊ฐ๋ฅผ ํฌํจํฉ๋๋ค. ์ด ์ฅ์ ๋ค์ด๋๋ฏน ๋ชจ๋์ ์ฃผ์ ๋ฅผ ํ์ฅํฉ๋๋ค. ์๋ฃ๋๋ฉด ์์ ์ด ๋ฌด์์ธ์ง, ์ธ์  ์ด๋ป๊ฒ ์ฌ์ฉํ๋์ง ์ ํ์ ํด์ผํฉ๋๋ค.
Introduction
์ค๋ช
์์ ๊ฐ์ ์น์
์์๋ ๋๋ถ๋ถ์ ์์ฉ ํ๋ก๊ทธ๋จ ์ฝ๋ ์์ ๋ ์ผ๋ฐ ๋๋ static ๋ชจ๋์ ์ฌ์ฉํฉ๋๋ค. ๋ชจ๋์ ํ๋ก ๋ฐ์ด๋ ๋ฐ ์ปจํธ๋กค๋ฌ์ ๊ฐ์ด ์ ์ฒด ์์ฉ ํ๋ก๊ทธ๋จ์ ๋ชจ๋ ์ ๋ถ๋ถ์ผ๋ก ๊ตฌ์ฑ๋๋ ๊ตฌ์ฑ ์์ ๊ทธ๋ฃน์ ์ ์ํฉ๋๋ค. ์ด๋ฌํ ๊ตฌ์ฑ ์์์ ๋ํ ์คํ ์ปจํ
์คํธ ๋๋ ๋ฒ์๋ฅผ ์ ๊ณตํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ๋ชจ๋์ ์ ์ ๋ ๊ณต๊ธ์๋ ๋ด๋ณด๋ผ ํ์์์ด ๋ชจ๋์ ๋ค๋ฅธ ๊ตฌ์ฑ์์๊ฒ ํ์๋ฉ๋๋ค. ๊ณต๊ธ์๊ฐ ๋ชจ๋ ์ธ๋ถ์์ ๋ณผ ์ ์์ด์ผํ๋ ๊ฒฝ์ฐ, ๋จผ์  ํธ์คํธ ๋ชจ๋์์ _exported_๋ฅผ ์ฌ์ฉํ ๋ค์ ์๋น ๋ชจ๋๋ก _imported_ํฉ๋๋ค.
์ต์ํ ์๋ฅผ ์ดํด ๋ณด๊ฒ ์ต๋๋ค.
๋จผ์ UsersService๋ฅผ ์ ๊ณตํ๊ณ  ๋ด๋ณด๋ด๋ UsersModule์ ์ ์ํฉ๋๋ค. UsersModule์ UsersService์ host ๋ชจ๋์
๋๋ค.
import { Module } from '@nestjs/common';
import { UsersService } from './users.service';
@Module({
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}๋ค์์ผ๋ก UserModule์ ๊ฐ์ ธ ์์ UserModule์ ๋ด ๋ณด๋ธ ๊ณต๊ธ์๋ฅผ AuthModule๋ด์์ ์ฌ์ฉํ  ์ ์๋๋กํ๋ AuthModule์ ์ ์ํฉ๋๋ค.
import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';
@Module({
  imports: [UsersModule],
  providers: [AuthService],
  exports: [AuthService],
})
export class AuthModule {}์ด๋ฌํ ๊ตฌ๋ฌธ์ ํตํด ์๋ฅผ ๋ค์ด AuthModule์์ ํธ์คํ
๋๋ AuthService์ UserService๋ฅผ ์ฝ์
 ํ  ์ ์์ต๋๋ค.
import { Injectable } from '@nestjs/common';
import { UsersService } from '../users/users.service';
@Injectable()
export class AuthService {
  constructor(private readonly usersService: UsersService) {}
  /*
    Implementation that makes use of this.usersService
  */
}์ด๊ฒ์ ์ ์ (static) ๋ชจ๋ ๋ฐ์ธ๋ฉ์ด๋ผ๊ณ ํฉ๋๋ค. Nest๊ฐ ๋ชจ๋์ ์๋ก ์ฐ๊ฒฐํ๋ ๋ฐ ํ์ํ ๋ชจ๋  ์ ๋ณด๋ ์ด๋ฏธ ํธ์คํธ ๋ฐ ์๋น ๋ชจ๋์์ ์ ์ธ๋์์ต๋๋ค. ์ด ๊ณผ์ ์์ ์ผ์ด๋๋ ์ผ์ ํ์ด๋ณด๊ฒ ์ต๋๋ค. Nest๋AuthModule ๋ด์์UsersService๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉ ๊ฐ๋ฅํ๊ฒํฉ๋๋ค.
UsersModule์์ฒด๊ฐ ์๋นํ๋ ๋ค๋ฅธ ๋ชจ๋์ ์  ์ด์ ์ผ๋ก ๊ฐ์ ธ์ค๊ณ ์ข ์์ฑ์ ์  ์ด์ ์ผ๋ก ํด๊ฒฐํ๋ ๊ฒ์ ํฌํจํ์ฌUsersModule์ธ์คํด์คํ (Custom provider ์ฐธ์กฐ)AuthModule์ ์ธ์คํด์คํํ๊ณUsersModule์ ๋ด ๋ณด๋ธ ๊ณต๊ธ์๋ฅผAuthModule์ ๊ตฌ์ฑ ์์์์ ์ฌ์ฉํ ์ ์๋๋กํฉ๋๋ค (AuthModule์์ ์ ์ธ ๋ ๊ฒ์ฒ๋ผ).AuthService์UsersService์ ์ธ์คํด์ค๋ฅผ ์ฃผ์ ํฉ๋๋ค.
Dynamic module use case
์ ์  ๋ชจ๋ ๋ฐ์ธ๋ฉ์ ์ฌ์ฉํ๋ฉด ์๋น ๋ชจ๋์ด ํธ์คํธ ๋ชจ๋์ ๊ณต๊ธ์๊ฐ ๊ตฌ์ฑ๋๋ ๋ฐฉ์์ ์ํฅ์ ์ค ์์๋ ๊ธฐํ๊ฐ ์์ต๋๋ค. ์ด๊ฒ์ด ์ ์ค์ํ๊ฐ? ๋ค๋ฅธ ์ฌ์ฉ ์ฌ๋ก์์ ๋ค๋ฅด๊ฒ ์๋ํด์ผํ๋ ๋ฒ์ฉ ๋ชจ๋์ด์๋ ๊ฒฝ์ฐ๋ฅผ ๊ณ ๋ คํ์ญ์์ค. ์ด๋ ๋ง์ ์์คํ ์์ "ํ๋ฌ๊ทธ์ธ"๊ฐ๋ ๊ณผ ์ ์ฌํ๋ฉฐ ์ผ๋ฐ ๊ธฐ๋ฅ์ ์๋น์๊ฐ ์ฌ์ฉํ๊ธฐ ์ ์ ์ผ๋ถ ๊ตฌ์ฑ์ด ํ์ํฉ๋๋ค.
Nest์ ์ข์ ์๋ ๊ตฌ์ฑ ๋ชจ๋์ ๋๋ค. ๋ง์ ์์ฉ ํ๋ก๊ทธ๋จ์ ๊ตฌ์ฑ ๋ชจ๋์ ์ฌ์ฉํ์ฌ ๊ตฌ์ฑ ์ธ๋ถ ์ ๋ณด๋ฅผ ์ธ๋ถํํ๋ ๊ฒ์ด ์ ์ฉํ๋ค๋ ๊ฒ์ ์๊ณ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ๊ฐ๋ฐ์๋ฅผ์ํ ๊ฐ๋ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค, ์ค๋น / ํ ์คํธ ํ๊ฒฝ์์ํ ์ค๋น ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ฑ ๋ค์ํ ๋ฐฐํฌ ํ๊ฒฝ์์ ์์ฉ ํ๋ก๊ทธ๋จ ์ค์ ์ ์ฝ๊ฒ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค. ๊ตฌ์ฑ ๋งค๊ฐ ๋ณ์ ๊ด๋ฆฌ๋ฅผ ๊ตฌ์ฑ ๋ชจ๋, ์์ฉ ํ๋ก๊ทธ๋จ ์์ค ์ฝ๋์ ์์ํจ์ผ๋ก์จ ๊ตฌ์ฑ ๋งค๊ฐ ๋ณ์์ ๋ ๋ฆฝ์ ์ผ๋ก ์ ์ง๋ฉ๋๋ค.
๋ฌธ์ ๋ ๊ตฌ์ฑ ๋ชจ๋ ์์ฒด๊ฐ ์ผ๋ฐ ( "ํ๋ฌ๊ทธ์ธ"๊ณผ ์ ์ฌํ๊ธฐ ๋๋ฌธ์) ์๋น ๋ชจ๋์ ๋ฐ๋ผ ์ฌ์ฉ์ ์ ์ํด์ผํ๋ค๋ ๊ฒ์ ๋๋ค. ์ฌ๊ธฐ์์ dynamic modules์ด ์์๋ฉ๋๋ค. ๋์  ๋ชจ๋ ๊ธฐ๋ฅ์ ์ฌ์ฉํ์ฌ ์๋น ๋ชจ๋์ด API๋ฅผ ์ฌ์ฉํ์ฌ ๊ตฌ์ฑ ๋ชจ๋์ ๊ฐ์ ธ์ฌ ๋ ์ฌ์ฉ์ ์ ์ํ๋ ๋ฐฉ๋ฒ์ ์ ์ด ํ ์ ์๋๋ก ๊ตฌ์ฑ ๋ชจ๋์ ๋์ ์ผ๋ก ๋ง๋ค ์ ์์ต๋๋ค.
๋ค์ ๋งํด, ๋์  ๋ชจ๋์ ํ ๋ชจ๋์ ๋ค๋ฅธ ๋ชจ๋๋ก ๊ฐ์ ธ์ค๊ณ , ์ง๊ธ๊น์ง ๋ณธ ์ ์  ๋ฐ์ธ๋ฉ์ ์ฌ์ฉํ๋ ๊ฒ๊ณผ ๋ฐ๋๋ก ๋ชจ๋์ ๊ฐ์ ธ์ฌ ๋ ํด๋น ๋ชจ๋์ ์์ฑ๊ณผ ๋์์ ์ฌ์ฉ์ ์ ์ํ๊ธฐ์ํ API๋ฅผ ์ ๊ณตํฉ๋๋ค.
Config module example
์ด ์น์ ์์๋ configuration chapter์ ์์  ์ฝ๋ ๊ธฐ๋ณธ ๋ฒ์ ์ ์ฌ์ฉํฉ๋๋ค. ์ด ์ฅ์ ๋์์ ์์ฑ ๋ ๋ฒ์ ์ ์์ ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ฐ๋ฆฌ์ ์๊ตฌ ์ฌํญ์ ConfigModule์ด options ๊ฐ์ฒด๋ฅผ ๋ฐ์ ๋ค์ฌ ์ปค์คํฐ๋ง์ด์ฆ ํ๋๋ก ํ๋ ๊ฒ์
๋๋ค. ์ง์ํ๋ ค๋ ๊ธฐ๋ฅ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ๊ธฐ๋ณธ ์ํ์ .env ํ์ผ์ ์์น๋ฅผ ํ๋ก์ ํธ ๋ฃจํธ ํด๋์ ํ๋ ์ฝ๋ฉํฉ๋๋ค. ์ ํํ ํด๋์์ .env ํ์ผ์ ๊ด๋ฆฌ ํ  ์ ์๋๋ก ๊ตฌ์ฑ ๊ฐ๋ฅํ๊ฒ ๋ง๋ค๊ณ  ์ถ๋ค๊ณ  ๊ฐ์  ํด ๋ด
์๋ค. ์๋ฅผ ๋ค์ด, ๋ค์ํ .env ํ์ผ์ config๋ผ๋ ํ๋ก์ ํธ ๋ฃจํธ ์๋์ ํด๋ (์: src์ ํ์  ํด๋)์ ์ ์ฅํ๋ค๊ณ  ๊ฐ์  ํด๋ณด์ญ์์ค. ๋ค๋ฅธ ํ๋ก์ ํธ์์ ConfigModule์ ์ฌ์ฉํ  ๋ ๋ค๋ฅธ ํด๋๋ฅผ ์ ํํ  ์ ์์ต๋๋ค.
๋์  ๋ชจ๋์ ๊ฐ์ ธ ์ค๋ ๋ชจ๋์ ๋งค๊ฐ ๋ณ์๋ฅผ ์ ๋ฌํ์ฌ ํด๋น ๋์์ ๋ณ๊ฒฝํ  ์์๋ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค. ์ด๊ฒ์ด ์ด๋ป๊ฒ ์๋ํ๋์ง ๋ด
์๋ค. ์๋น ๋ชจ๋์ ๊ด์ ์์ ์ด๊ฒ์ด ์ด๋ป๊ฒ ๋ณด์ผ์ง์ ๋ํ ์ต์ข
 ๋ชฉํ์์ ์์ํ์ฌ ๊ฑฐ๊พธ๋ก ์์
ํ๋ฉด ๋์์ด๋ฉ๋๋ค. ๋จผ์ , ConfigModule์ ๊ฐ์ ธ ์ค๋ _statically_ ๊ฐ์ ธ ์ค๊ธฐ (์ฆ, ๊ฐ์ ธ์จ ๋ชจ๋์ ๋์์ ์ํฅ์ ์ค ์์๋ ์ ๊ทผ ๋ฐฉ๋ฒ)๋ฅผ ๋น ๋ฅด๊ฒ ๊ฒํ ํด ๋ณด๊ฒ ์ต๋๋ค. @Module()๋ฐ์ฝ๋ ์ดํฐ์ imports ๋ฐฐ์ด์์ฃผ์๋ฅผ ๊ธฐ์ธ์ด์ญ์์ค :
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from './config/config.module';
@Module({
  imports: [ConfigModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}๊ตฌ์ฑ ๊ฐ์ฒด๋ฅผ ์ ๋ฌํ๋ _dynamic module_ import๊ฐ ์ด๋ป๊ฒ ๋ณด์ผ์ง ์๊ฐํด ๋ด
์๋ค. ์ด ๋ ์์ ์ imports ๋ฐฐ์ด์ ์ฐจ์ด์ ์ ๋น๊ตํ์ญ์์ค.
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from './config/config.module';
@Module({
  imports: [ConfigModule.register({ folder: './config' })],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}์์ ๋์  ์์์ ๋ฌด์จ ์ผ์ด ์ผ์ด๋๋์ง ๋ด ์๋ค. ์์ง์ด๋ ๋ถ๋ถ์ ๋ฌด์์ ๋๊น?
ConfigModule์ ์ผ๋ฐ ํด๋์ค์ด๋ฏ๋กregister()๋ผ๋ ์ ์  ๋ฉ์๋๊ฐ ์์ด์ผ ํจ์ ์ ์ถํ ์ ์์ต๋๋ค. ์ฐ๋ฆฌ๋ ํด๋์ค์ ์ธ์คํด์ค๊ฐ ์๋๋ผConfigModuleํด๋์ค์์ ํธ์ถํ๊ธฐ ๋๋ฌธ์ ์ ์ ์์ ์๊ณ ์์ต๋๋ค. ์ฐธ๊ณ : ๊ณง ๋ง๋ค ์ด ๋ฉ์๋๋ ์์์ ์ด๋ฆ์ ๊ฐ์ง ์ ์์ง๋ง, ๊ด๋ก ์ ์ผ๋กforRoot()๋๋register()๋ผ๊ณ ๋ถ๋ฆ ๋๋ค.register()๋ฉ์๋๋ ์ฐ๋ฆฌ์ ์ํด ์ ์๋๋ฏ๋ก ์ํ๋ ์ ๋ ฅ ์ธ์๋ฅผ ๋ฐ์ ๋ค์ผ ์ ์์ต๋๋ค. ์ด ๊ฒฝ์ฐ ์ ์ ํ ์์ฑ์ ๊ฐ์ง ๊ฐ๋จํoptions๊ฐ์ฒด๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ด๊ฒ์ด ์ผ๋ฐ์ ์ธ ๊ฒฝ์ฐ์ ๋๋ค.register()๋ฉ์๋๋ ๋ฆฌํด ๊ฐ์ด ์ต์ํimports๋ฆฌ์คํธ์ ๋ํ๋๊ธฐ ๋๋ฌธ์module๊ณผ ๊ฐ์ ๊ฒ์ ๋ฐํํด์ผํ๋ค๊ณ ์ ์ถ ํ ์ ์์ต๋๋ค. ์ฌ๊ธฐ์๋ ๋ชจ๋๋ฆฌ์คํธ๊ฐ ํฌํจ๋์ด ์์ต๋๋ค.
์ฌ์ค, register() ๋ฉ์๋๊ฐ ๋ฆฌํด ํ  ๊ฒ์ DynamicModule์
๋๋ค. ๋์  ๋ชจ๋์ ์ ์  ๋ชจ๋๊ณผ ๋์ผํ ์ ํํ ์์ฑ๊ณผ module์ด๋ผ๋ ์ถ๊ฐ ์์ฑ์ ๊ฐ์ง ๋ฐํ์์ ์์ฑ๋ ๋ชจ๋์ ์ง๋์ง ์์ต๋๋ค. ๋ฐ์ฝ๋ ์ดํฐ์ ์ ๋ฌ๋ ๋ชจ๋ ์ต์
์์ฃผ์๋ฅผ ๊ธฐ์ธ์ด๋ฉด์ ์ํ ์ ์  ๋ชจ๋ ์ ์ธ์ ๋น ๋ฅด๊ฒ ๊ฒํ ํด ๋ณด๊ฒ ์ต๋๋ค.
@Module({
  imports: [DogsService],
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService]
})๋ค์ด๋๋ฏน ๋ชจ๋์ ์ ํํ ๊ฐ์ ์ธํฐํ์ด์ค๋ฅผ ๊ฐ์ง ๊ฐ์ฒด์ module์ด๋ผ๋ ์ถ๊ฐ ์์ฑ์ ๋ฐํํด์ผํฉ๋๋ค. module ์์ฑ์ ๋ชจ๋ ์ด๋ฆ์ผ๋ก ์ฌ์ฉ๋๋ฉฐ ์๋ ์์ ์ ๊ฐ์ด ๋ชจ๋์ ํด๋์ค ์ด๋ฆ๊ณผ ๋์ผํด์ผํฉ๋๋ค.
info ํํธ ๋์  ๋ชจ๋์ ๊ฒฝ์ฐ ๋ชจ๋ ์ต์  ๊ฐ์ฒด์ ๋ชจ๋ ์์ฑ์ ์ ํ ์ฌํญ์ ๋๋ค except
module.
์ ์  register()๋ฉ์๋๋ ์ด๋ป์ต๋๊น? ์ด์  ๊ทธ ์ญํ ์ DynamicModule ์ธํฐํ์ด์ค๋ฅผ ๊ฐ์ง ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ ๊ฒ์์ ์ ์ ์์ต๋๋ค. ์ฐ๋ฆฌ๊ฐ ๊ทธ๊ฒ์ ํธ์ถ ํ  ๋, ์ฐ๋ฆฌ๋ ์ ์  ํด๋์ค์์ ๋ชจ๋ ํด๋์ค ์ด๋ฆ์ ๋์ดํจ์ผ๋ก์จ ๊ทธ๋ ๊ฒํ๋ ๊ฒ๊ณผ ์ ์ฌํ ๋ฐฉ์์ผ๋ก ๋ชจ๋์ imports ๋ชฉ๋ก์ ํจ๊ณผ์ ์ผ๋ก ์ ๊ณตํฉ๋๋ค. ๋ค์ ๋งํด, ๋์  ๋ชจ๋ API๋ ๋จ์ํ ๋ชจ๋์ ๋ฐํํ์ง๋ง @Modules ๋ฐ์ฝ๋ ์ดํฐ์ ์์ฑ์ ์์ ํ๋ ๋์  ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์์ผ๋ก ์ง์ ํฉ๋๋ค.
์ฌ์ง์ ์์ฑํ๋ ๋ฐ ๋์์ด๋๋ ๋ช ๊ฐ์ง ์ธ๋ถ ์ ๋ณด๊ฐ ์ฌ์ ํ ์์ต๋๋ค.
์ด์ 
@Module()์ ๋ฐ์ฝ๋ ์ดํฐ์imports์์ฑ์ ๋ชจ๋ ํด๋์ค ์ด๋ฆ (์:imports: [UsersModule])๋ฟ๋ง ์๋๋ผ ๋์  ํจ์ returning ํจ์๋ฅผ ์ฌ์ฉํ ์ ์์์ ์ ์ ์์ต๋๋ค ๋ชจ๋ (์:imports: [ConfigModule.register(...)]).๋์  ๋ชจ๋ ์์ฒด๋ ๋ค๋ฅธ ๋ชจ๋์ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค. ์ด ์์ ์์๋ ๊ทธ๋ ๊ฒํ์ง ์์ง๋ง ๋์  ๋ชจ๋์ด ๋ค๋ฅธ ๋ชจ๋์ ๊ณต๊ธ์์ ์์กดํ๋ ๊ฒฝ์ฐ ์ ํ์ 
imports์์ฑ์ ์ฌ์ฉํ์ฌ ๊ฐ์ ธ์ต๋๋ค. ๋ค์, ์ด๊ฒ์@Module()๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ ์  ๋ชจ๋์ ๋ํ ๋ฉํ ๋ฐ์ดํฐ๋ฅผ ์ ์ธํ๋ ๋ฐฉ์๊ณผ ์ ํํ ์ ์ฌํฉ๋๋ค.
์ด๋ฌํ ์ดํด๋ฅผ ๋ฐํ์ผ๋ก ์ด์  ๋์  ConfigModule์ ์ธ์ ๋ชจ์ต์ ๋ณผ ์ ์์ต๋๋ค. ๊ทธ๊ฒ์ ๊ท ์ด์ ๋ณด์.
import { DynamicModule, Module } from '@nestjs/common';
import { ConfigService } from './config.service';
@Module({})
export class ConfigModule {
  static register(): DynamicModule {
    return {
      module: ConfigModule,
      providers: [ConfigService],
      exports: [ConfigService],
    };
  }
}์ด์  ์กฐ๊ฐ๋ค์ด ์ด๋ป๊ฒ ๋ฌถ์ฌ ์๋์ง ๋ถ๋ช
ํด์ผํฉ๋๋ค. ConfigModule.register(...)๋ฅผ ํธ์ถํ๋ฉด ์ง๊ธ๊น์ง @Module() ๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ํตํด ๋ฉํ ๋ฐ์ดํฐ๋ก ์ ๊ณต ํ ๊ฒ๊ณผ ๋ณธ์ง์ ์ผ๋ก ๋์ผํ ์์ฑ์ ๊ฐ์ง DynamicModule ๊ฐ์ฒด๋ฅผ ๋ฐํํฉ๋๋ค.
info ํํธ
@nestjs/common์์DynamicModule์ ๊ฐ์ ธ์ต๋๋ค.
๊ทธ๋ฌ๋ ๋์  ๋ชจ๋์ ๊ทธ๋ค์ง ํฅ๋ฏธ๋กญ์ง ์์ง๋ง, ์ฐ๋ฆฌ๊ฐ ์ํ๋๋๋ก ๊ตฌ์ฑํ๋ ๊ธฐ๋ฅ์ ๋์ ํ์ง ์์์ต๋๋ค. ๋ค์์ ๊ทธ ๋ด์ฉ์ ๋ค๋ฃจ๊ฒ ์ต๋๋ค.
Module configuration
ConfigModule์ ๋์์ ์ปค์คํฐ๋ง์ด์ฆํ๊ธฐ์ํ ํ์คํ ํด๊ฒฐ์ฑ
์ ์์์ ์๊ฐํ ๊ฒ์ฒ๋ผ ์ ์  register()๋ฉ์๋์์ options ๊ฐ์ฒด๋ฅผ ์ ๋ฌํ๋ ๊ฒ์
๋๋ค. ์๋น ๋ชจ๋์ imports ์์ฑ์ ๋ค์ ํ๋ฒ ์ดํด ๋ณด์.
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from './config/config.module';
@Module({
  imports: [ConfigModule.register({ folder: './config' })],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}๊ทธ๊ฒ์ '์ต์
'๊ฐ์ฒด๋ฅผ ๋์  ๋ชจ๋์ ์ ๋ฌํ๋ ๊ฒ์ ์ ์ฒ๋ฆฌํฉ๋๋ค. ๊ทธ๋ฌ๋ฉดConfigModule์์options ๊ฐ์ฒด๋ฅผ ์ด๋ป๊ฒ ์ฌ์ฉํฉ๋๊น? ์ ์ ์๊ฐํด ๋ด
์๋ค. ์ฐ๋ฆฌ๋ConfigModule์ด ๊ธฐ๋ณธ์ ์ผ๋ก ๋ค๋ฅธ ์ ๊ณต์๊ฐ ์ฌ์ฉํ๊ธฐ ์ํด ์ฃผ์ฌ ๊ฐ๋ฅํ ์๋น์ค ์ธConfigService๋ฅผ ์ ๊ณตํ๊ณ  ๋ด๋ณด๋ด๋ ํธ์คํธ๋ผ๋ ๊ฒ์ ์๊ณ  ์์ต๋๋ค. ์ค์ ๋ก ๋์์ ์ฌ์ฉ์ ์ ์ํ๊ธฐ ์ํดoptions ๊ฐ์ฒด๋ฅผ ์ฝ์ด์ผํ๋ ๊ฒ์ 'ConfigService'์
๋๋ค. register ()๋ฉ์๋์์ConfigService๋กoptions '๋ฅผ ์ป๋ ๋ฐฉ๋ฒ์ ์๊ณ  ์๋ค๊ณ  ๊ฐ์ ํ์. ์ด ๊ฐ์ ์ ํตํด ์๋น์ค์ ์ผ๋ถ๋ฅผ ๋ณ๊ฒฝํ์ฌoptions` ๊ฐ์ฒด์ ์์ฑ์ ๋ฐ๋ผ ๋์์ ์ฌ์ฉ์ ์ง์ ํ  ์ ์์ต๋๋ค. ( ์ฐธ๊ณ   : ๋น๋ถ๊ฐ์ ์ค์ ๋ก ์ ๋ฌํ๋ ๋ฐฉ๋ฒ์ ๊ฒฐ์  ํ์ผ๋ฏ๋ก '์ต์
'์ ํ๋ ์ฝ๋ฉ ๋งํ๋ฉด๋ฉ๋๋ค. ์ ์ ํ์ ์์ ํ๊ฒ ์ต๋๋ค.)
import { Injectable } from '@nestjs/common';
import * as dotenv from 'dotenv';
import * as fs from 'fs';
import { EnvConfig } from './interfaces';
@Injectable()
export class ConfigService {
  private readonly envConfig: EnvConfig;
  constructor() {
    const options = { folder: './config' };
    const filePath = `${process.env.NODE_ENV || 'development'}.env`;
    const envFile = path.resolve(__dirname, '../../', options.folder, filePath);
    this.envConfig = dotenv.parse(fs.readFileSync(envFile));
  }
  get(key: string): string {
    return this.envConfig[key];
  }
}์ด์  ConfigService๋ options์์ ์ง์ ํ ํด๋์์ .env ํ์ผ์ ์ฐพ๋ ๋ฐฉ๋ฒ์ ์๊ณ  ์์ต๋๋ค.
์ฐ๋ฆฌ์ ๋๋จธ์ง ์์
์ register()๋จ๊ณ์ options ๊ฐ์ฒด๋ฅผ ConfigService์ ์ฝ์
ํ๋ ๊ฒ์
๋๋ค. ๋ฌผ๋ก  _dependency injection_์ ์ฌ์ฉํ์ฌ ์ํํฉ๋๋ค. ์ด๊ฒ์ด ํต์ฌ ์ฌํญ์ด๋ฏ๋ก ์ดํดํด์ผํฉ๋๋ค. ์ฐ๋ฆฌ์ ConfigModule์ ConfigService๋ฅผ ์ ๊ณตํ๊ณ  ์์ต๋๋ค. ConfigService๋ ๋ฐํ์์๋ง ์ ๊ณต๋๋ options ๊ฐ์ฒด์ ์์กดํฉ๋๋ค. ๋ฐ๋ผ์ ๋ฐํ์์ ๋จผ์  options ๊ฐ์ฒด๋ฅผ Nest IoC ์ปจํ
์ด๋์ ๋ฐ์ธ๋ฉ ํ ๋ค์ Nest๊ฐ ConfigService์ ์ฝ์
ํด์ผํฉ๋๋ค. ๋ง์ถค ์ ๊ณต์ ์ฅ์์ ์ ๊ณต์๋ ์๋น์ค๋ฟ๋ง ์๋๋ผ ๋ชจ๋  ๊ฐ์น๋ฅผ ํฌํจ ํ  ์ ์๋ค๋ ์ ์ ๊ธฐ์ตํ์ญ์์ค. ์์กด์ฑ ์ฃผ์
์ ์ฌ์ฉํ์ฌ ๊ฐ๋จํ options ๊ฐ์ฒด๋ฅผ ์ฒ๋ฆฌํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
์ต์
 ๊ฐ์ฒด๋ฅผ IoC ์ปจํ
์ด๋์ ๋ฐ์ธ๋ฉํ๋ ๋ฐฉ๋ฒ์ ๋จผ์  ์ดํด ๋ณด๊ฒ ์ต๋๋ค. ์ ์  register()๋ฉ์๋์์ ์ด๋ฅผ ์ํํฉ๋๋ค. ์ฐ๋ฆฌ๋ ๋์ ์ผ๋ก ๋ชจ๋์ ๊ตฌ์ฑํ๊ณ  ์์ผ๋ฉฐ ๋ชจ๋์ ์์ฑ ์ค ํ๋๋ ๊ณต๊ธ์ ๋ชฉ๋ก์
๋๋ค. ๋ฐ๋ผ์ ์ฐ๋ฆฌ๊ฐํด์ผ ํ  ์ผ์ ์ต์
 ๊ฐ์ฒด๋ฅผ ๊ณต๊ธ์๋ก ์ ์ํ๋ ๊ฒ์
๋๋ค. ์ด๋ฅผ ํตํด ConfigService์ ์ฃผ์
 ํ  ์์๊ฒ ๋๋ฉฐ ๋ค์ ๋จ๊ณ์์ ํ์ฉํ  ๊ฒ์
๋๋ค. ์๋ ์ฝ๋์์providers ๋ฐฐ์ด์์ฃผ์ํ์ญ์์ค :
import { DynamicModule, Module } from '@nestjs/common';
import { ConfigService } from './config.service';
@Module({})
export class ConfigModule {
  static register(options): DynamicModule {
    return {
      module: ConfigModule,
      providers: [
        {
          provide: 'CONFIG_OPTIONS',
          useValue: options,
        },
        ConfigService,
      ],
      exports: [ConfigService],
    };
  }
}์ด์  CONFIG_OPTIONS์ ๊ณต์๋ฅผ ConfigService์ ์ฝ์
ํ์ฌ ํ๋ก์ธ์ค๋ฅผ ์๋ฃ ํ  ์ ์์ต๋๋ค. ๋น ํด๋์ค ํ ํฐ์ ์ฌ์ฉํ์ฌ ๊ณต๊ธ์๋ฅผ ์ ์ ํ  ๋๋ ์ฌ๊ธฐ์ ์ค๋ช
๋๋๋ก @Inject() ๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ์ฌ์ฉํด์ผํฉ๋๋ค.
import { Injectable, Inject } from '@nestjs/common';
import * as dotenv from 'dotenv';
import * as fs from 'fs';
import { EnvConfig } from './interfaces';
@Injectable()
export class ConfigService {
  private readonly envConfig: EnvConfig;
  constructor(@Inject('CONFIG_OPTIONS') private options) {
    const filePath = `${process.env.NODE_ENV || 'development'}.env`;
    const envFile = path.resolve(__dirname, '../../', options.folder, filePath);
    this.envConfig = dotenv.parse(fs.readFileSync(envFile));
  }
  get(key: string): string {
    return this.envConfig[key];
  }
}๋ง์ง๋ง ์ฐธ๊ณ  ์ฌํญ: ๋จ์ํ๋ฅผ ์ํด ์์ ๋ฌธ์์ด ๊ธฐ๋ฐ ์ฃผ์
 ํ ํฐ (CONFIG_OPTIONS)์ ์ฌ์ฉํ์ง๋ง ๋ชจ๋ฒ ์ฌ๋ก๋์ด๋ฅผ ๋ณ๋์ ํ์ผ์์ ์์ (๋๋ ์ฌ๋ณผ)๋ก ์ ์ํ๊ณ  ํด๋น ํ์ผ์ ๊ฐ์ ธ ์ค๋ ๊ฒ์
๋๋ค. ์๋ฅผ ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
export const CONFIG_OPTIONS = 'CONFIG_OPTIONS';Example
์ด ์ฅ์ ์ฝ๋์ ๋ํ ์ ์ฒด ์๋ ์ฌ๊ธฐ์์ ํ์ธํ ์ ์์ต๋๋ค.
Last updated
Was this helpful?