NestJS에서 package.json의 version 적용하기

@ZungTa · 2022-05-30 월요일 · 2 min read

발단

NestJS 프로젝트에 버전을 적용하려고 했다.

V1, V2 이런 API Versioning 말고 package.json에 Version을 작성해서 그 값을 Frontend에서 확인할 수 있게 하자는 취지였다.

문제

Version용 Application Module을 만들었고, package.json에 버전 쓰는 것까지는 좋았는데 Version을 반환해주는 API를 만들면서 문제가 생겼다.

version.service.ts에서 package.json을 import 해서 쓰기 때문에 build할 때 dist 디렉터리의 구조가 바뀌어버린다.

자세하게 말하면 원래는 dist 아래에 module들이 나열되어 있었는데 version.service.ts에서 src 바깥에 있는 package.json을 참조하게 되면서 src 디렉터리까지 빌드에 포함되어서 dist 디렉터리 아래에 src 디렉터리가 생기고 그 안에 모듈들이 나열되는 구조로 바뀌었다.

// version.service.ts
import { Injectable } from "@nestjs/common"
import { version } from "../../package.json"
@Injectable()
export class VersionService {
  async getVersion() {
    return { version }
  }
}

version module 없을 때 dist 구조

version module 없을 때 dist 구조

version module을 사용할 때 dist 구조

version module을 사용할 때 dist 구조

이것만으로는 별문제가 생기진 않는다.

하지만 npm script로 start 명령어를 구성해 놓은게 node dist/main 으로 해놨기 때문에 start할 때 문제가 발생한다.

dist/main 경로가 아닌 dist/src/main으로 바뀌기 때문이다.

해결

이 문제점을 해결하기 위해서 package.json을 직접 import 하지 않고 fs 모듈을 써서 동적으로 파일의 내용을 가져오도록 변경하였다.

예외 처리는 덤으로.

import { Injectable, InternalServerErrorException } from "@nestjs/common"
import * as fs from "fs"
import * as path from "path"

@Injectable()
export class VersionService {
  async getVersion() {
    const packageJsonFilePath = path.join(__dirname, "..", "..", "package.json")
    const rawData = fs.readFileSync(packageJsonFilePath)
    const packageJson = JSON.parse(rawData.toString())

    if (!("version" in packageJson)) {
      throw new InternalServerErrorException(
        "can not found version in package.json"
      )
    }
    const { version } = packageJson

    return { version }
  }
}

참고할 것

  • JSON을 import 할 때 tsconfig에서 resolveJsonModule을 true로 주지 않으면 아래와 같은 오류가 발생한다.
    Cannot find module '../../package.json'. Consider using '--resolveJsonModule' to import module with '.json' extension.
@ZungTa
I'm a backend developer
© ZungTa Devlog, Built with Gatsby