동적 모듈은 모듈이 생성 될대 동적으로 어떠한 변수들이 정해집니다.
즉 호스트 모듈을 가져다 쓰는 소비 모듈에서 호스트 모듈을 생성할 때 동적으로 값을 설정하는 방식 입니다

정적 모듈에 비해 동적 모듈ㅇ르 사용하면 코드가 간결해집니다.
동적 모듈의 대표적인 예로 보통 config 라고 부르는 모듈이 있습니다.
Config 모듈은 실행 환경에 따라 서버에 설정되는 환경 변수를 관리하는 모듈입니다.

ConfigModule을 동적으로 생성하는 예를 보기 전에 잠시 NodeJS 서버에서 일반적으로 사용하는 환경 변수 관리 방법을 살펴 보겠다.

.env를 이용한 Config 설정

서비스를 개발할 때 local 혹은 development라 부르는 개발자 PC환경에서 개발과 테스트를 하고 개발한 코드를 stage 서버라고 부릅니다.
테스트 환경에 배포하여 통합 테스트를 진행합니다.
이후 테스트 서버 환경에 문제가 없다면 다시 production 서버로 배포하는 과정을 거칩니다ㅣ.

이렇게 실행 환경이 달라지게 되는데 실행 환경에 따라 달라지는 변수들이 있습니다.
연결할 데이터 베이스의 호스트 이름이 DATABASE_HOST라는 환경 변수가 있다고 할 때 이 환경 변수의 값은 각각의 환경에 따라 다른 이름을 가지게 됩니다.

환경 마다 다른 host 이름을 가지는 데이터 베이스에 연결하기 위해 코드를 따로 작성해야 하는 것은 매우 비효율 적입니다.

NodeJS에는 dotenv라는 유명한 라이브러리가 존재합니다.
각 환경 변수를 .env 확장자를 가진 파일에 저장해두고, 서버가 구동될때, 이 파일을 읽어 해당 값을 환경 변수로 설정해주는 역할을 합니다.

npm i --save dotenv
npm i --save-dev @types/dotenv

dotenv는 기본으로 루트 디렉터리에 존재하는 .env 확장자를 가진 파일을 읽습니다.
위에서 예로 들었던 DATABASE_HOST라는 환경 변수를 각 파일에 저장합니다.

.development.env

DATABASE_HOST=local

.stage.env

DATABASE_HOST=stage-reader.dextto.com

.production.env

DATABASE_HOST=prod-reader .dextto.com

매번 터미널을 새로 열때마다, NODE_ENV를 새로 설정하는 것은 귀찮기 때문에, package.json 에 아래와 같이 셋팅하게 된다면, 간편하게 셋팅이 가능하다.

"scripts":{
	"prebuild": "rimraf dist",
	...
	"start:dev" : "npm run prebuild && NODE_ENV=development nest start --watch"
}

Nest에서 제공하는 Config 패키지

앞 절에서는 dotenv 패키지를 직접 사용하는 방법을 살펴 봤습니다.
그런데 Nest는 dotenv를 내부적으로 활용하는 @nestjs/config 패키지를 제공합니다.

이를 이용해서 ConfigModule을 동적으로 생성할 수 있습니다.

npm i --save @nestjs/config

이 패키지에는 ConfigModule 이름을 가진 모듈이 이미 존재합니다.
이 모듈을 동적 모듈로 가져옵니다.

import { ConfigModule }  from '@nestjs/config';

@Module({
	imports: [ConfigModule.forRoot()],
})
export class AppModule { }

정적 모듈을 가져올 때와는 달리 ConfigModule.forRoot() 메서들르 호출하는 것을 볼 수 있습니다.
forRoot 메서드는 DynamicModule을 리턴하는 정적 메서드 입니다.

동적 모듈을 작성할 때 forRoot라는 이름 대신 어떤 다른 이름을 써도 상관 없지만, 관례상 forRootregister를 붙입니다.
비동기 함수일 때는 forRootAsync, registerAsync로 합니다.

static forRoot(options?: ConfigModuleOptions) : DynamicModule

인수로는 ConfigModuleOptions를 받습니다.
즉, ConfigModule은 소비 모듈이 원하는 옵션값을 전달하여 원하는 대로 동적으로 ConfigModule을 생성합니다.
ConfigModule을 위와 같이 가져왔다면, 프로젝트의 루트 디렉터리에 있는 .env 파일을 찾아 환경 변수로 등록합니다.
우리는 3개의 .env 파일을 가지고 있으므로 envFilePath 옵션을 주도록 해야합니다.

import { ConfigModule } from '@nestjs/config'

@Module({
	imports: [ConfigModule.forRoot({
		envFilePath: (process.env.NODE_ENV === 'production' ) ? '.production.env'
		: (process.env.NODE_ENV === 'stage' ) ? '.stage.env' : '.development.env'
	})],
	controllers: [AppController],
	providers: [AppService, ConfigService],
})
export class AppModule{ }

User Service에 환경 변수 구성하기

npm i @nestjs/config
npm i joi

환경 변수의 유효성 검사를 위한 joi 라이브러리도 설치 하겠습니다.

.development.env

EMAIL_SERVICE=Gmail
EMAIL_AUTH_USER=YOUR_GMAIL
EMAIL_AUTH_PASSWORD=GMAIL_PASSWORD
EMAIL_BASE_URL=http://localhost:3000

#Back #NodeJS #NestJS