NestJS env 파일을 yaml로 작성해보자!

HanSH·2024년 6월 18일

NestJS

목록 보기
27/29
post-thumbnail

env를 작성하려면 DATABASE_PORT=3306 이런식으로 해야하지만, 전부 적용하면

FIREBASE_API_KEY=AIzaSyBJlrwvAvO
FIREBASE_AUTH_DOMAIN=nestjs-a319
FIREBASE_DATABASE_URL=https://ne
FIREBASE_STORAGE_BUCKET=nestjs-a
FIREBASE_SENDER_ID=56433121320
FIREBASE_APP_ID=1:56433121320:we
FIREBASE_MEASUREMENT_FNT_ID=G-4N

FIREBASE_TYPE=service_account
FIREBASE_PROJECT_ID=nestjs-a319f
FIREBASE_PROJECT_KEY_ID=47c7cb18
FIREBASE_PRIVATE_KEY="-----BEGIN
FIREBASE_CLIENT_EMAIL=firebase-a
FIREBASE_CLIENT_ID=1173015623794
FIREBASE_AUTH_URI=https://accoun
FIREBASE_TOKEN_URI=https://oauth
FIREBASE_AUTH_CERT_URL=https://w
FIREBASE_CLIENT_CERT_URL=https:/
FIREBASE_UNIVERSE_DOMAIN=googlea

이런식으로 매우 더러워져요.

firebase:
  apiKey: 'AIzaSyBJlrw
  projectId: "nestjs-a
  auth:
    domain: "nestjs-a3
    databaseUrl: "http
    storageBucket: "ne
    senderId: "5643312
    appId: "1:56433121
    measurementFntId: 
  admin:
    URI:
      auth: "https://a
      authCert: "https
      clientCert: "htt
      token: "https://
    type: "service_acc
    privateKeyId: "47c
    privateKey: "-----
    clientEmail: "fire
    clientId: "1173015
    universeDomain: "g

이런식으로 깔끔하게 적용할 수 있으면 얼마나 좋을까요?
NestJS의 ServiceModule에서는 이를 지원해줘요!

ConfigModule 설정

YAML 적용

npm i --save @nestjs/config로 먼저 ConfigModule을 설치해주세요.

$ npm i js-yaml // yaml load
$ npm i -D @types/js-yaml // yaml의 타입을 사용할 수 있게 함

이후 yaml 파일을 불러올 수 있도록 해주는 모듈을 설치해줍시다!

이후 적용은 아래와 같이 해주시면 돼요!

// config/configuration.ts
import { readFileSync } from 'fs';
import * as yaml from 'js-yaml';
import { join } from 'path';

const YAML_CONFIG_FILENAME = 'config.yaml';

export default () => {
  return yaml.load(
    readFileSync(join(__dirname, YAML_CONFIG_FILENAME), 'utf8'),
  ) as Record<string, any>;
};
// app.module.ts
import configuration from './config/configuration';

@Module({
  imports: [
    ConfigModule.forRoot({
      load: [configuration],
      // isGlobal: true, // global으로 사용하고자 할때 적용
    }),
  ],
})
export class AppModule {}

ConfigService 사용

기존에 사용했던 .env와 동일하게 사용하면 돼요. 다만 yaml에서 불러온 만큼 각 entity의 연결을 .으로 하게 돼요.

즉, configService.get<T>('firebase.admin.URI.token') 이런식으로 사용하면 돼요!

트러블 슈팅

먼저 알고 가야 할 사항을 몇 가지 작성할게요.

  1. 현재 제 디렉토리 구조는 아래와 같아요. 디렉터리 구조
.
├── dist
│   ├── app.controller.d.ts
...
│   ├── app.service.d.ts
│   ├── app.service.js
│   ├── app.service.js.map
│   ├── config
│   │   ├── env.d.ts
│   │   ├── env.js
│   │   └── env.js.map
│   ├── firebase
│   │   ├── firebase.config.d.ts
│   │   ├── firebase.config.js
│   │   └── firebase.service.js.map
│   ├── main.d.ts
│   ├── main.js
│   ├── main.js.map
│   └── tsconfig.build.tsbuildinfo
├── env.yaml
├── nest-cli.json
├── package-lock.json
├── package.json
└── src
    ├── config
    │   └── env.ts
    ├── firebase
    │   ├── firebase.config.ts
    │   └── firebase.service.ts
    └── main.ts
  1. compilerOptions의 assets의 구조에요.
    • include: sourceRoot를 기준
    • outDir: 최상위 디렉터리를 기준
    이 때문에 ourDir에 ./dist/config 또는 dist/config로 작성이 된거에요.

ENOENT: no such file or directory

NestJS는 TS 파일이나 JS 파일만 자동으로 옮겨줍니다. 사용자 정의 파일, 즉 Asset은 자동으로 옮겨주지 않아요.
따라서 build시 Asset을 복사하도록 설정해줘야합니다!
해당 내용은 이쪽에서 참고해주세요!

{
  ...
  "sourceRoot": "src",
  "compilerOptions": {
    "deleteOutDir": true,
    "assets": [{ "include": "env.yaml", "outDir": "dist/config", "watchAssets": true }]
  }
}

그랬는데도 파일이 복사가 안된다..?

build시 파일 복사의 기준이 되는 디렉토리는 src입니다. 작성한 env 파일은 src와 같은 레벨이 아닌 한 단계 높은 레벨에 있기 때문에 수정해주셔야 합니다.
만약 src 디렉터리보다 낮은 레벨, 즉 src 디렉터리 하위에 env 파일이 있다면 dir/dir/dir/.../env.yaml과 같은 형식으로 적을 수 있어요!

"assets": [
  { 
    "include": "../env.yaml", 
    "outDir": "dist/config", 
    "watchAssets": true 
  }
]

Error: cant go up that far

분명 상위 레벨에 있어서 상대 경로로 접근했는데 왜 이 오류가 발생할까요?

NestJS는 프로젝트의 최상위 디렉터리의 데이터를 옮길 수 없게 되어있습니다. 따라서 최상위 디렉터리에 있는 env 파일을 옮길 수 없었던거죠.

해결 방법은 2가지입니다.

  1. 최상위 디렉터리에 하위 디렉터리를 만들고(config) 그 안에 env 파일을 넣는다.

    이 경우,

    "assets": [
     { 
       "include": "../config/env.yaml", 
       "outDir": "dist/config", 
       "watchAssets": true 
     }
    ]

    이런식으로 작성할 수 있어요!

  2. src 폴더에 넣는다.

    이 경우,

    "assets": [
     { 
       "include": "env.yaml", 
       "outDir": "dist/config", 
       "watchAssets": true 
     }
    ]

    이런식으로 작성할 수 있어요!

profile
저는 말하는 싹 난 감자입니다

0개의 댓글