개발일지

[NestJS] 환경변수 설정하기 - config, cross-env, joi 본문

NestJS, Node.js/#01 Project - 투표 커뮤니티

[NestJS] 환경변수 설정하기 - config, cross-env, joi

lyjin 2022. 11. 16.

@nestjs/config

보통 개발할 때와 배포할 때의 실행 환경이 달라지기 때문에 환경 변수들을 분리하여 관리할 필요가 있습니다. NestJS에서는 dotenv를 내부적으로 활용하는 @nestjs/config 패키지를 제공해줍니다. 이를 이용하여 ConfigModule을 동적으로 생성할 수 있습니다.

 

$ yarn add @nestjs/config --save

 

 

환경 변수를 관리하는 env 파일을 생성했습니다. `.env.development` 는 개발 환경에서, `.env.production` 배포 환경에서 사용됩니다.

 

├── .env.development
└── .env.production

 


ConfigModule

// app.module.ts
import { ConfigModule } from '@nestjs/config';
import configuration from './config/configuration';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
      load: [configuration],
      envFilePath:
        process.env.NODE_ENV == 'production'
          ? '.env.production'
          : '.env.development',
    })
  ]
})
  • isGlobal: boolean : true일 경우 ConfigModule을 전역 모듈로 선언합니다.
  • load: [] : 개별적으로 생성한 설정 파일들을 로드할 수 있습니다.
  • envFilePath : env 파일 경로를 설정합니다.

 

// config/configuration.ts

export default () => ({
  port: parseInt(process.env.PORT) || 3000,
});

main.ts에서 ConfigService 사용하기

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

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  const configService = app.get(ConfigService);
  const host = configService.get('port');

  await app.listen(host);
}
bootstrap();

 


cross-env

맥OS, 윈도우, 리눅스 등 운영체제마다 환경변수를 설정하는 방법이 다릅니다. cross-env는 이를 해결하기위해 만들어진 모듈로, 모든 운영체제에서 동일한 방법으로 환경 변수를 변경할 수 있게 합니다.

 

$ yarn add cross-env --save

package.json

환경변수 부분(NODE_ENV=...) 앞에 cross-env만 붙여주면 됩니다.

 

{
  "scripts": {
    ...
    "start:dev": "cross-env NODE_ENV=development nest start --watch",
    "start:prod": "cross-env NODE_ENV=production node dist/main.js",
    }
}

 

 


joi - 환경변수 유효성 검사하기

환경변수로 undefined처럼 잘못된 값이 들어와서는 안됩니다. joi 패키지를 사용하여 환경변수 유효성 검증 스키마를 정의할 수 있습니다. 🔗 joi API Reference

 

$ yarn add joi --save

 

// app.module.ts
import * as Joi from 'joi';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
      load: [configuration],
      envFilePath:
        process.env.NODE_ENV == 'production'
          ? '.env.production'
          : '.env.development',
      // 유효성 검사
      validationSchema: Joi.object({
        NODE_ENV: Joi.string()
          .valid('development', 'production')
          .default('development'),
        PORT: Joi.number().default(3000),
      }),
    }),
  ],
})