Nestjs@cli가 내 6시간을 뺏어갔어요.

hwibaski·2022년 1월 10일
1

개발일지

목록 보기
10/10

어쩌다가 그런 일이..

최근 Nest.js에 관심이 생겨서 강의와 자료들을 찾아서 공부해보고 있습니다.

제일 먼저 진행했던 컨텐츠는 노마드코더님의 NestJS로 API 만들기였습니다. Nest.js는 Express.js와 다르게 처음부터 프로젝트 구조를 생성할 필요가 없습니다.

CREATE-REACT-APP과 같이 프로젝트 생성 명령을 내리면, 일정한 템플릿처럼 프로젝트가 생성이 되죠.
그것을 위해 첫 단계로 필요한 것이 바로 Nestjs@cli 입니다.
문제는 노마드코더님의 강의를 진행할 때는 잘만 동작하던 Nestjs@cli가 3일이 지난 후 명령어를 사용하니까 아래와 같이 이상한 메세지를 보내왔습니다.

2022.01.13 추가 - 이게 간단한 버그의 문제가 아니였습니다. 관련된 내용을 링크로 대신합니다

???????


2번째 사진과 같이 정상적인 메세지를 출력해야 하는데 기괴한 메세지가 출력되었습니다. 이걸 해결하기 위해 시간을 꽤 낭비했습니다만, 이 기회에 제 node가 어디 설치되어 있는지도 정확히 알게 되었고, package.json의 기능 또한 알게된 부분이 있어서 기록을 남기려합니다.



1. 처음으로 한 일 - 구글링

무조건 구글링을 처음으로 했습니다. 근데 이건 에러메세지가 없다보니까 처음에 이걸 뭐라고 검색해야되지? 라는 생각이 가장 먼저 들었습니다. 'nest cli에 버그가 있다.', 'nest cli 명령어가 안 된다.' 이런 검색을 했었습니다. 검색결과는 최소 몇 개월이 지난 글들이 많았고, 검색 결과의 4~5페이지까지 뒤져봐도 유의미한 결과를 얻기는 힘들었습니다. 그래도 그 와중에 얻게된 것들도 있었습니다.

저는 1번의 명령어를 사용하고자 했습니다. 하지만 기괴한 결과를 얻었죠. 2번의 명령어를 사용해도 npx를 이용하여 1번과 같은 결과를 얻을 수 있다는 거죠. nestjs@cli를 전역으로 설치하지 않아도 같은 결과 값을 얻을 수 있다는 사실을 알게 됐습니다. 하지만 문제는 두 가지의 명령어 모두 이상한 메세지를 출력했습니다.

  1. nest new project-name

  2. npx @nestjs/cli new project-name

검색 결과에 맞는 것은 없고, 많은 사람들이 겪고 있지 않는 버그라면, 혹시 내 local 환경의 문제가 아닐까? 혹시 내 node 설치 환경이 꼬여있는건 아닌가? 라는 생각을 두 번째로 했습니다.



2. 두 번째로 한 일 - 내 로컬 환경 테스트 해보기

저는 노드를 처음으로 설치한 것은 약 4개월 전입니다. 그 때 당시 어떻게 설치하는지도 몰라서 homebrew 명령어를 무지성으로 복붙하기도 했고, nvm이라는 것을 써보라는 글을 봐서 nvm을 이용해서 node를 설치하기도 했습니다.

여러가지 환경의 노드가 제 맥북에 있었던거죠. 그래서 global에 패키지를 설치하면 brew로 설치한 global 노드 모듈이 실행이 되나, 아니면 nvm으로 사용하고 있는 노드의 환경에서 실행되나 라는 의문이 들었습니다. 하나하나 확인해본 것은 아닙니다만, nvm의 글로벌 node_module 디렉토리에 제가 여태 전역으로 설치한 패키지들이 잘 설치되어 있었고, 여태 사용을 해왔기 때문에 nvm으로 관리되는 node가 brew로 관리되는 node보다 우선순위를 가질 것이다 정도로 추정을 했습니다.

하지만 혹시 모를 상황이니 제가 현재 사용하고 있는 nvm v14.17.1 버전의 노드를 제외하고 다른 노드 환경은 다 삭제해버렸습니다. 모든 노드 환경을 정리하고 나서 패키지를 재설치한 후 nestjs@cli가 설치된 위치를 정확히 확인한 후 명령을 실행했고, 여러가지 버전을 테스트해봤습니다만, 얻는 결과는 같았습니다.

그리고 나서 알게된 것

  • 전역으로 패키지를 설치 시 아래의 node_modules 디렉토리에 설치된다는 것(nvm 사용 시)

  • nvm으로 설치한 노드는 아래의 디렉토리에 설치된다는 것



3. 세 번째로 한 일 - 다른 환경에서의 테스트 해보기

이쯤되니 혹시 나의 맥이랑 현재 패키지랑 호환이 맞지 않는가?라는 생각이 들었습니다. 그래서 저는 제 Window PC와 Amazon EC2에서 테스트를 해봐야겠다고 생각했습니다. 우선 잘 쓰지도 않던 Window PC를 켜고 노드를 설치했습니다. 키보드를 버벅여가며 nestjs@cli를 실행시켰습니다(이 과정에서 npm 명령어를 사용하기 위한 몇 가지 설정을 했습니다.)만 결과는 동일했습니다. EC2의 환경에서도 테스트를 진행했습니다만 동일한 결과를 얻었습니다. 이 테스트를 진행하고 나서 저는 제 환경의 문제는 아니라고 생각이 들었습니다.

  • EC2에서의 테스트



4. 네 번째로 한 일 - 질문하기

제 환경은 문제가 아니라고 생각했는데, 막상 검색 결과에 안 나오니 뭐 어떻게 해결해야되지? 라는 생각이 들었습니다. 그래서 저는 스택오버플로우에 글을 썼습니다. 한 30분 정도만에 답글이 달렸습니다. '최소한 이 주제로 글을 쓰기 전에 관련된 이슈가 있는지 확인좀해줄래? 여기에 이미 글 있잖아' 라는 댓글과 함께 츤데레처럼 링크를 달아주신 분이 계셨습니다.(제가 작성한 글은 중복적인 내용으로 인해 삭제했습니다.)

해당 글은 약 2시간 전에 작성된 글이었고 저랑 같은 에러를 겪고 있었습니다. 민망함도 잠시... 너무 반가웠습니다. 생성된지 얼마되지 않은 따끈따끈한 이슈였습니다. nestjs 측에서 해당 이슈를 인식을 하고 있었고, PR이 생성되어 있었습니다.



5. 왜 이런 일이 일어났나요?

해당 이슈를 살펴보니 종속된 패키지에서 문제가 있는 것 같았습니다. colors 패키지에서 문제가 생겼고, colors를 사용하는 cli-table3라는 패키지도 문제를 일으켜 터미널에서 정상적인 결과를 출력해줄 수 없다는 것으로 파악했습니다. nestjs의 개발자 분이 수습이 되기까지 colors의 패키지 버전을 1.4.0으로 고정해서 사용해달라는 코멘트를 올려주셨습니다.

아래의 이미지는 nestjs@cli, cli-table3 그리고 colors 패키지의 종속성 관계입니다.



6. 패키지 버전 고정? 종속된 패키지들 다 찾아서 수정해줘야되나요?

저는 resolutions 라는 옵션을 또 처음 알게 됐습니다. resolutions 사용법으로 사용법을 익힌 후 아래의 package.json을 수정했습니다. 간단하게 말씀드리면 resoloutions 옵션은 하위의 패키지의 버전을 원하는 버전으로 고정할 수 있는 기능입니다. package.json을 수정하고, @nestjs/cli의 최상위 디렉토리에서 npm install 명령어를 실행하니 기존 문제가 있었던 colors 1.4.1 버전이 1.4.0 버전으로 다운그레이드 되었고, 문제 없이 nest 명령어를 사용할 수 있었습니다.

{
  "name": "@nestjs/cli",
  "version": "8.1.6",
  "description": "Nest - modern, fast, powerful node.js web framework (@cli)",
  "publishConfig": {
    "access": "public"
  },
  "engines": {
    "node": ">= 10.13.0",
    "npm": ">= 6.11.0"
  },
  "bin": {
    "nest": "bin/nest.js"
  },
  "scripts": {
    "build": "tsc",
    "clean": "gulp clean:bundle",
    "format": "prettier --write \"**/*.ts\"",
    "lint": "eslint '{lib,commands,actions}/**/*.ts' --fix",
    "start": "node bin/nest.js",
    "prepack": "npm run build",
    "prepublish:next": "npm run build",
    "publish:next": "npm publish --access public --tag next",
    "prepublish:npm": "npm run build",
    "publish:npm": "npm publish --access public",
    "test": "jest --config test/jest-config.json",
    "test:dev": "npm run clean && jest --config test/jest-config.json --watchAll",
    "prerelease": "npm run build",
    "release": "release-it",                        
    "preinstall": "npx npm-force-resolutions"         // <---  ******* 새로 입력한 부분 **********
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/nestjs/nest-cli.git"
  },
  "contributors": [
    "Kamil Mysliwiec <mail@kamilmysliwiec.com>",
    "Mark Pieszak <mark@trilon.io>",
    "ThomRick"
  ],
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/nestjs/nest-cli/issues"
  },
  "homepage": "https://github.com/nestjs/nest-cli#readme",
  "dependencies": {
    "@angular-devkit/core": "13.1.1",
    "@angular-devkit/schematics": "13.1.1",
    "@angular-devkit/schematics-cli": "13.1.1",
    "@nestjs/schematics": "^8.0.3",
    "chalk": "3.0.0",
    "chokidar": "3.5.2",
    "cli-table3": "0.6.0",
    "commander": "4.1.1",
    "fork-ts-checker-webpack-plugin": "6.5.0",
    "inquirer": "7.3.3",
    "node-emoji": "1.11.0",
    "ora": "5.4.1",
    "os-name": "4.0.1",
    "rimraf": "3.0.2",
    "shelljs": "0.8.4",
    "source-map-support": "0.5.21",
    "tree-kill": "1.2.2",
    "tsconfig-paths": "3.12.0",
    "tsconfig-paths-webpack-plugin": "3.5.2",
    "typescript": "4.3.5",
    "webpack": "5.65.0",
    "webpack-node-externals": "3.0.0"
  },
  "devDependencies": {
    "@commitlint/cli": "15.0.0",
    "@commitlint/config-angular": "15.0.0",
    "@types/copyfiles": "2.4.1",
    "@types/inquirer": "7.3.3",
    "@types/jest": "27.0.3",
    "@types/node": "16.11.12",
    "@types/node-emoji": "1.8.1",
    "@types/ora": "3.2.0",
    "@types/os-name": "3.1.0",
    "@types/rimraf": "3.0.2",
    "@types/shelljs": "0.8.9",
    "@types/webpack-node-externals": "2.5.3",
    "@typescript-eslint/eslint-plugin": "5.6.0",
    "@typescript-eslint/parser": "5.6.0",
    "delete-empty": "3.0.0",
    "eslint": "8.4.1",
    "eslint-config-prettier": "8.3.0",
    "eslint-plugin-import": "2.25.3",
    "gulp": "4.0.2",
    "gulp-clean": "0.4.0",
    "husky": "7.0.4",
    "jest": "27.4.4",
    "prettier": "2.5.1",
    "release-it": "14.11.8",
    "ts-jest": "27.1.1",
    "ts-loader": "9.2.6",
    "ts-node": "10.4.0"
  },
  "husky": {
    "hooks": {
      "commit-msg": "commitlint -c .commitlintrc.json -E HUSKY_GIT_PARAMS"
    }
  },
  "resolutions": {     // <---  ******* 새로 입력한 부분 **********
    "colors": "1.4.0"
  }
}


7. 번외 : cli-table3의 package.json 살펴보기

cli-table3은 optionalDependencies라는 옵션으로 colors 패키지 가지고 있었습니다.
문제가 됐던 colors 패키지의 버전은 1.4.1 입니다. 하지만 ^1.1.2라고 적혀져있습니다.

^1.1.2는 1.1.2 버전보다 상위 버전, 그리고 2.0.0 버전 보다는 하위버전의 패키지의 범위를 의미하는 겁니다. 1.1.2보다 colors 패키지의 버전의 높고 2.0.0보다 낮으면 그 버전이 자동으로 설치되는 것이죠.

optionalDependencies는 colors 패키지가 만약에 설치가 되지 않더라도, 빌드의 오류를 발생하지 않고 넘어갑니다. 저는 'colors 패키지 없어도 그냥 진행해' 정도로 생각했습니다. colors 패키지는 기능적으로 중요하다기 보다 색상을 나타내는 패키지기 때문에 이렇게 설정한 것이 아닐까 하는 추측을 해봅니다.

하지만 이번에는 패키지 자체의 설치가 문제가 있었던 것은 아니므로, 설치는 완료 됐지만, 내부적으로 다른 문제를 일으켰던 것으로 예상해봅니다.

{
  "name": "cli-talbe3",
  
   ...다른 옵션들...
  
  "optionalDependencies": {
    "colors": "^1.1.2"
  }
}

8. 결론

  • 종속된 패키지들의 버전을 package.json의 resolutions 옵션으로 조절할 수 있다.
  • 구글링이 안 되는 에러는 정말 최신의 따끈 따끈한 버그일 수도 있다.
  • 현재는 nestjs@cli가 8.1.8 버전으로 재배포되어 정상적으로 이용가능합니다!!



9. reference

https://github.com/nestjs/nest-cli/issues/1480
https://npmgraph.js.org/?q=%40nestjs%2Fcli
https://stackoverflow.com/questions/70646085/nestjs-cli-outputs-garbage
https://heropy.blog/2018/02/18/node-js-npm/
https://blog.outsider.ne.kr/1041
https://revf.tistory.com/m/256?fbclid=IwAR0s7sMZ0_MxRwmK26SZ9U7z612zDjn09k5yT6eKe01tF-07TorCns5uc5o

1개의 댓글

comment-user-thumbnail
2022년 2월 25일

ㅋㅋㅋㅋㅋㅋ제목 어그로ㅋㅋㅋㅋ 최고의 problem solver십니다👍🏻

답글 달기

관련 채용 정보