본문 바로가기
Back-end/기초부터 따라하는 nest.js

#7. 기초부터 따라하는 Nest.js : cross-env를 이용한 scripts에서의 환경변수 관리

by hsloth 2023. 4. 2.

 

해당 포스팅은 nest.js 9.0.0 버전, typeorm 0.3.x 버전을 기준으로 작성되었습니다.
모든 글은 작성자의 주관이 100% 담겨있기 때문에 부정확할 수 있습니다.

 

#pre. 터미널을 켜고 프로젝트 폴더로 이동

https://suloth.tistory.com/44

 

#0-1. 기초부터 따라하는 nest.js : 터미널 키는 법 + 터미널에서 작업 폴더 이동

윈도우 윈도우는 윈도우+R 버튼을 누른 후, cmd 를 입력하여 터미널을 킵니다. 혹은 윈도우 버튼을 눌러서 검색창에 cmd를 검색하면 터미널이 나올텐데 그걸 실행시켜주시면 됩니다. Mac OS Mac의 경

suloth.tistory.com

 
위의 링크의 내용을 참고하여 study 폴더로 이동해줍니다.
그리고 code . 명령어를 통해 vscode를 열어줍니다.


이전 포스팅에서 Nest.js 에서 환경변수를 다루는 법을 알아보았습니다.

https://suloth.tistory.com/65

 

#6. 기초부터 따라하는 Nest.js : dotenv와 ConfigModule을 이용한 환경변수 관리

해당 포스팅은 nest.js 9.0.0 버전, typeorm 0.3.x 버전을 기준으로 작성되었습니다. 모든 글은 작성자의 주관이 100% 담겨있기 때문에 부정확할 수 있습니다. #pre. 터미널을 켜고 프로젝트 폴더로 이동 ht

suloth.tistory.com

 

이번 포스팅에서는 cross-env를 이용하여 scripts에서 환경변수를 다루는 법을 알아보겠습니다.


cross-env


cross-env는 scripts에서 환경변수를 설정할 때, OS간의 호환성 문제를 해결하기 위해 존재하는 모듈입니다.

그냥, scripts에서 환경변수를 사용할 때 필요한 모듈이라고 생각합시다.

 

프로젝트를 실행시킬 때, 개발을 위해 서버를 실행시킬 때도 있고, 배포해서 실제 서비스를 위해서 서버를 실행시킬 때도 있습니다.

서비스를 스크립트 명령에 따라 개발모드, 배포모드 등으로 실행시키고 싶을 때 주로 사용합니다.

 

Start

cross-env를 설치합니다. (설치는 항상 프로젝트 최상위 폴더 혹은 package.json이 위치한 폴더에서 이루어져야합니다)

npm i cross-env

 

그 다음, scripts를 다음과 같이 변경해줍시다.

  "scripts": {
    "prebuild": "rimraf dist",
    "build": "nest build",
    "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
    "start": "nest start",
    "start:dev": "cross-env NODE_ENV=dev nest start --watch",
    "start:prod": "cross-env NODE_ENV=prod node dist/main",
    "schema:drop": "ts-node ./node_modules/typeorm/cli.js schema:drop -d ./data-source.ts",
    "schema:sync": "ts-node ./node_modules/typeorm/cli.js schema:sync -d ./data-source.ts",
    "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
    "test": "jest",
    "test:watch": "jest --watch",
    "test:cov": "jest --coverage",
    "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
    "test:e2e": "jest --config ./test/jest-e2e.json"
  },

start:dev 와 start:prod를 수정했습니다.

cross-env를 사용하여 NODE_ENV라는 환경변수의 값을 dev와 prod로 각각 설정하고 명령을 실행한다는 뜻입니다. 

 

그리고, app.module.ts 파일로 가서 코드를 다음과 같이 고쳐줍시다.

// app.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import * as path from 'path';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UserModule } from './res/user/user.module';
import { ConfigModule, ConfigService } from '@nestjs/config';

console.log(`.env.${process.env.NODE_ENV}`);

@Module({
  imports: [
    ConfigModule.forRoot({
      envFilePath: `.env.${process.env.NODE_ENV}`,
      isGlobal: true,
    }),
    TypeOrmModule.forRootAsync({
      inject: [ConfigService],
      useFactory: (configService: ConfigService) => ({
        retryAttempts: configService.get('NODE_ENV') === 'prod' ? 10 : 1,
        type: 'mysql',
        host: configService.get('DB_HOST'),
        port: Number(configService.get('DB_PORT')),
        database: configService.get('DB_NAME'),
        username: configService.get('DB_USER'),
        password: configService.get('DB_PASSWORD'),
        entities: [
          path.join(__dirname, 'src/entities/**/*.entity.{js, ts}'),
        ],
        synchronize: false,
        logging: true,
        timezone: 'local',
      }),
    }),
    UserModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

 

console.log(`.env.${process.env.NODE_ENV}`); 를 통해 env 파일 이름이 잘 찍히는지 확인합니다.

ConfigModule.forRoot의 옵션에 envFilePath: `.env.${process.env.NODE_ENV}` 를 추가해 NODE_ENV라는 환경변수에 따라 다른 env 파일을 불러오도록 합시다. 여기서 따옴표는 `(백틱)을 사용합니다. ~물결표시를 쉬프트를 떼고 누르면 백틱을 칠수 있습니다.

 

그리고, data-source.ts 도 마찬가지로 코드를 수정하도록 합시다.

import * as path from 'path';
import { DataSource } from 'typeorm';
import * as dotenv from 'dotenv';

dotenv.config({ path: `.env.dev` });

export const dataSource = new DataSource({
  type: 'mysql',
  host: process.env.DB_HOST,
  port: Number(process.env.DB_PORT),
  database: process.env.DB_NAME,
  username: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  entities: [
    path.join(__dirname, 'src/entities/**/*.entity.ts'),
    path.join(__dirname, 'dist/entities/**/*.entity.js'),
  ],
  synchronize: false,
  logging: true,
});

dotenv.config에 path를 추가해주었습니다.

 

그리고 npm run schema:sync를 하면 오류가 뜹니다.

 

왜냐하면, .env.dev라는 파일이 존재하지 않기 때문입니다.

 

cross-env를 통해 환경변수인 NODE_ENV를 받도록 변경하였으니, .env파일도 그에 맞게 파일명을 수정해주어야 합니다.

원래 존재하던 .env 파일을 .env.dev 로 이름을 바꾸고, .env.prod 파일도 만들어줍시다.

.env.dev 파일에는 개발시 사용할 환경변수를 넣고, (ex. 테스트 DB명)

.env.prod 파일에는 실제 배포시 사용할 환경변수를 넣읍시다. (ex. AWS RDS의 호스트명과 DB명)

이번 포스팅에서는 .env.dev만 사용할 예정입니다.

 

그리고 npm run schema:sync를 하면 오류가 안뜰겁니다.

 

이로써  cross-env를 통한 환경변수 관리는 끝입니다!

 


주의사항


앞으로, 서버를 돌릴 때는 npm run start:dev 명령어를 사용해서 돌리도록 합시다.

 

.gitignore 파일에 .env*를 추가해주도록 합시다. 그래야 .env 관련 파일들이 github에 올라가지 않습니다.

 


Github에 Push


다음 포스팅을 참고하여 github에 코드를 push합시다.

https://suloth.tistory.com/46

 

#0-2. 기초부터 따라하는 Nest.js : Git과 Github 사용법

이 글은 아래의 포스팅에 이어서 작성하는 포스팅입니다. https://suloth.tistory.com/45 #1. 기초부터 따라하는 Nest.js : Nest.js 초기 설정 Nest.js란? node.js의 백엔드 프레임워크 중 하나입니다. node.js에는 수

suloth.tistory.com

 

참고하시라고 올려두는 사진