[Node.js 모듈 시스템 & 패키지 관리] 2. Node.js 패키지 관리

Shy·2023년 9월 8일
0

NodeJS(Express&Next.js)

목록 보기
25/39

npm이란?

npm은 Node Package Manager의 약자로 Node.js의 패키지 관리 도구이다. npm은 아래와 같은 주요 기능과 특징을 갖는다.

  1. 패키지 설치: Node.js로 작성된 라이브러리나 프레임워크를 설치할 수 있다. 예를 들면, npm install express 명령어를 통해 Express.js 프레임워크를 설치할 수 있다.

  2. 패키지 생성 및 배포: 자신만의 라이브러리나 도구를 만들어 npm 저장소에 배포할 수 있습. 이를 통해 다른 개발자들이 만든 패키지를 사용하거나, 자신의 패키지를 다른 사람에게 제공할 수 있다.

  3. package.json: 이 파일은 Node.js 프로젝트의 메타데이터를 포함하며, 프로젝트의 의존성, 스크립트, 버전 정보 등을 정의힌다. npm은 이 파일을 통해 어떤 패키지가 필요한지, 어떤 명령을 실행해야 하는지 등의 정보를 알 수 있다.

  4. 의존성 관리: 프로젝트에서 사용하는 모든 패키지의 의존성을 자동으로 관리한다. npm install 명령을 실행하면 package.json에 나열된 모든 의존성이 설치된다.

  5. 글로벌 설치: 특정 패키지를 전역적으로 설치하여 시스템의 어느 곳에서나 명령어로 해당 패키지를 사용할 수 있게 할 수 있다. 예를 들면, npm install -g nodemon을 통해 nodemon을 글로벌로 설치할 수 있다.

  6. 버전 관리: package.json과 package-lock.json 파일을 통해 프로젝트의 의존성 패키지의 특정 버전을 지정하거나 업데이트 할 수 있다.

  7. 스크립트 실행: package.json의 scripts 섹션을 통해 명령어 스크립트를 정의하고 npm run 명령으로 해당 스크립트를 실행할 수 있다.

  8. npm 저장소: 전 세계의 개발자들이 만든 수 많은 패키지를 찾을 수 있는 중앙 저장소 역할을 한다. npmjs.com에서 패키지 정보를 검색하고 문서를 찾아볼 수 있다.

간단히 말해, npm은 Node.js 생태계의 핵심 부분으로, Node.js 개발자가 거의 모든 프로젝트에서 사용하는 도구이다.

npm package 설치하기

위와 같이 터미널에 npm init -y를 입력하면 package.json 파일이 생성된다.

{
  "name": "node-package-manager",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

axios package를 위와 같이 터미널에 입력해 설치하자.
그러면 package.json파일의dependencies에 axios가 추가된다.

{
  "name": "node-package-manager",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "axios": "^1.5.0"
  }
}

위 모듈을 사용하기 위한 예제 코드

const axios = require('axios');

axios.get('https://naver.com')
.then((response) => {console.log(response)})
.catch((error) => {console.log(error)})

node_module 살펴보기

axios라는 패키지 폴더 뿐 만 아니라, 이 패키지가 의존하고 있는 모듈 또한 포함되어 있다.

Sementic Versioning

아래 보는 것과 같이 노드 패키지들의 버전은 세 자리로 되어있다. 이는 세 자리가 모두 의미가 있다는 뜻의 Semantic Versioning이라고 하며 줄여서 SemVer이라고도 한다.

버전 번호 MAJOR.MINOR.PATCH가 주어지면 다음을 증가시킨다.

  1. 호환되지 않는 API변경 시 MAJOR버전
  2. 이전 버전과 호환되는 방식으로 기능을 추가하는 경우의 마이너 버전
  3. 이전 버전과 호환되는 버그 수정 시 PATCH버전

시험판 및 빌드 메타데이터에 대한 추가 레이블은 MAJOR.MINOR.PATCH 형식의 확장으로 사용할 수 있다.

~ (틸드)^ (캐럿)은 npm 패키지의 package.json 파일에서 의존성의 버전 범위를 지정할 때 사용하는 특별한 문자이다.

틸드 (~)

~ 뒤에 지정된 버전과 호환되는 패치 수준의 최신 버전을 허용한다.

  • 예:
    • ~1.2.3은 1.2.3부터 1.3.0 바로 전 버전까지 허용한다.
    • ~1.2는 1.2.0부터 1.3.0 바로 전 버전까지 허용한다.

캐럿 (^)

^ 뒤에 지정된 버전과 호환되는 마이너 수준의 최신 버전을 허용한다.
0의 주 버전 (예: 0.x.y)의 경우, 캐럿은 패치 수준의 변경만 허용한다.

    • ^1.2.3은 1.2.3부터 2.0.0 바로 전 버전까지 허용한다.
    • ^0.2.3은 0.2.3부터 0.3.0 바로 전 버전까지 허용한다.
    • ^0.0.3은 오직 0.0.3 버전만 허용한다.
  • 소프트웨어 1.0버전 전에는 API변경이 계속 일어난다. 그래서 0.3을 쓰다가 0.4를 사용하면 API가 호환이 안될수 있다. 그래서 0.x.x에서는 지정한 버전 자릿수 내에서만 업데이트한다.

이러한 규칙 덕분에 패키지 의존성 관리가 더 유연해진다. 개발자들은 의존성을 업데이트할 때, breaking change가 없는 범위 내에서 자동으로 패키지를 업데이트할 수 있게 된다.

package-lock.json

package-lock.json파일이란?

package-lock.json은 이 package-lock.json이 생성되는 시점의 의존성 트리(node_modules)에 대한 정보를 가지고 있는 파일을 말한다.

package-lock.json 파일은 Node.js 프로젝트의 의존성 트리에 대한 정확한 정보를 제공하는 역할을 한다. 이 파일을 사용하는 주요 이유는 다음과 같다.

  1. 일관성: 프로젝트를 다른 환경 또는 다른 개발자들 사이에서 공유할 때, package-lock.json 파일 덕분에 모든 개발자나 환경이 동일한 의존성 버전을 사용할 수 있다. 이로 인해 "내 컴퓨터에서는 잘 돌아가는데"와 같은 문제를 피할 수 있다.

  2. 속도 향상: node_modules를 재생성할 필요가 있을 때 (npm install을 실행할 때), package-lock.json이 있으면 NPM은 이 파일을 바탕으로 의존성 트리를 빠르게 재구축할 수 있다.

  3. 보안: package-lock.json은 의존성에 대한 정확한 버전 정보뿐만 아니라 각 패키지의 콘텐츠에 대한 해시도 포함하고 있다. 이로 인해, 악의적인 패키지 버전이 삽입되는 것을 방지할 수 있다.

  4. 분석: package-lock.json을 통해 프로젝트의 의존성 트리의 정확한 스냅샷을 얻을 수 있으므로, 어떤 의존성이 어떤 버전으로 설치되었는지, 그리고 그 의존성들 사이의 관계는 어떻게 되는지 쉽게 파악할 수 있다.

  5. 자동 생성 및 업데이트: npm install 명령을 사용하여 패키지를 추가, 업데이트, 제거할 때, package-lock.json 파일도 자동으로 업데이트된다. 따라서 개발자가 이 파일을 직접 수정할 필요는 없다.

결론적으로, package-lock.json은 프로젝트의 의존성 관리를 보다 안정적이고 예측 가능하게 만들어주는 중요한 도구이다.

위와 같이, 이렇게 버전의 범위 안에서 설치가 되면 현재는 1.3.1버전이 설치되지만, lodash의 버전이 업데이트된 상태로 publish가 된 후에, 동일한 package.json파일로 npm install을 실행했을 경우, 원래 버전이 아닌, 새러 업데이트된 버전으로 lodash로 설치가 된다.
이렇게 A는 1.3.1을 사용하고 이 package.json파일을 설치한 다른 사람은 다른 모듈과 버전 충돌이 일어날 수도 있다. 이러한 문제를 해결하기 위해서 package-lock.json을 사용한다.

npm audit

npm audit은 Node.js 프로젝트에서 사용하는 패키지의 보안 취약점을 검사하는 npm의 명령이다. 이 도구는 프로젝트의 package-lock.json 파일 또는 npm-shrinkwrap.json 파일에 기술된 의존성 전체 트리를 분석하여 알려진 취약점이 있는 패키지를 찾는다.

npm audit의 주요 기능 및 특징은 다음과 같다.

  1. 자세한 보고서 제공: npm audit을 실행하면, 발견된 취약점의 수준, 패키지 이름, 취약점에 대한 설명, 그리고 가능한 경우 수정 방법에 대한 권장사항 등의 정보를 제공한다.

  2. 자동 수정: npm audit fix 명령을 사용하면, 가능한 한 많은 취약점을 자동으로 수정할 수 있다. 이 명령은 안전하게 업그레이드 가능한 패키지를 업그레이드하고, 필요한 경우 일부 패키지를 대체한다.

  3. 수동 검토: 일부 취약점은 자동으로 해결할 수 없을 수 있다. 이 경우 npm audit은 문제에 대한 정보와 수동으로 해결할 수 있는 방법을 제공한다.

  4. 커스텀 보고서: npm audit은 다양한 출력 옵션을 제공하여, 보고서의 형식을 JSON이나 텍스트 등으로 변경할 수 있다. 이러한 기능은 CI/CD 파이프라인이나 자동화된 보안 스캔에 유용하게 사용될 수 있다.

npm audit은 개발자가 자신의 프로젝트에서 사용하는 패키지들 사이에 숨겨져 있는 보안 취약점을 감지하고 해결하는 데 도움을 준다. 이러한 취약점은 악의적인 공격자에게 프로젝트나 사용자의 데이터를 위협할 수 있기 때문에, 주기적으로 npm audit을 실행하여 프로젝트의 보안 상태를 확인하고 유지하는 것이 좋다.

npm install -g

패키지를 전역(Global)로 설치하려면 -g flag를 사용하면 된다.

전역으로 설치된 패키지는 디렉터리에 관계없이 작동한다.

npm install nodemon

nodemin은 디렉토리의 파일 변경이 감지되면 노드 응용 프로그램을 자동으로 다시 시작하여 Node.js기반 응용 프로그램을 개발하는 데 도움이 되는 도구이다.

nodemon은 코드나 개발 방법을 추가로 변경할 필요가 없다. nodemon은 노드의 대체 래퍼이다.
nodemon을 사용하려면 스크립트를 실행할 때 명령줄에서 node라는 단어를 바꾸면 된다.

  • ex) node index.js => nodemon index.js

전역설치 문제점

npm install -g 명령어는 전역(global) 범위로 패키지를 설치한다. 이렇게 전역으로 패키지를 설치할 때 다음과 같은 잠재적 문제점이 발생할 수 있다.

  1. 버전 충돌: 다양한 프로젝트가 동일한 전역 패키지의 서로 다른 버전을 필요로 할 수 있다. 한 프로젝트에서 필요로 하는 특정 버전의 패키지를 전역으로 설치하면, 다른 프로젝트에서는 해당 버전과 호환되지 않을 수 있다.

  2. 권한 문제: 특히 Linux 및 MacOS와 같은 일부 운영 체제에서 전역 패키지 설치는 관리자 권한을 필요로 할 수 있다. 이로 인해 권한 문제가 발생하거나, 의도치 않은 시스템 변경의 위험이 있다.

  3. 의존성 문제: 프로젝트의 의존성을 package.json 파일에 명시적으로 기록하지 않게 된다. 따라서 코드를 다른 환경으로 이동하거나 다른 개발자와 공유할 때 필요한 패키지가 누락될 위험이 있다.

  4. 불필요한 패키지: 시간이 지나면 어떤 패키지가 전역으로 설치되었는지 추적하기 어려울 수 있다. 이로 인해 불필요한 패키지가 시스템에 계속 남아있게 되며, 이는 시스템의 정리와 관리를 복잡하게 만들 수 있다.

  5. 보안 위험: 전역 패키지는 모든 사용자에게 사용 가능하다. 악의적인 패키지가 전역으로 설치되면 시스템 전체에 보안 위험이 발생할 수 있다.

따라서, 특정 프로젝트에 필요한 패키지는 해당 프로젝트의 디렉토리 내부에서 로컬로 설치하는 것이 좋다. 전역 설치는 일반적으로 CLI 도구나 다양한 프로젝트 간에 공유되는 도구의 경우에만 사용하는 것이 바람직하다.

Yarn이란?

Yarn은 페이스북, 구글 등 여러 회사에 의해 공동 발표된 프로젝트의 의존성을 관리하는 패키지 매니저이다.

Yarn은 npm의 대안으로 만들어졌으며, npm과 동일한 npm 저장소를 사용한다. 다만, Yarn은 의존성 설치의 속도와 보안성 향상, 더 나은 로컬 캐싱 시스템 등의 몇 가지 특징과 이점으로 주목받았다.

Yarn의 주요 특징 및 장점

  1. 속도: Yarn은 동시에 여러 패키지를 설치할 수 있어, 패키지 설치 속도가 빠르다. npm은 한 패키지를 다 설치하고 다 된 후에 다른 패키지를 순차적으로 설치한다.

  2. 보안: Yarn은 설치 전에 패키지의 코드 체크섬을 확인하여, 코드의 무결성을 검증한다.

  3. 결정론적 설치: 동일한 yarn.lock 파일과 package.json 파일이 주어지면, Yarn은 어디에서든 동일한 방식으로 의존성을 설치한다. 이는 다양한 환경에서 일관성 있는 설치를 보장한다.

  4. 오프라인 모드: 한 번 설치된 패키지는 로컬 캐시에 저장된다. 인터넷 연결이 없는 상황에서도 캐시된 패키지는 오프라인 모드로 재설치할 수 있다.

  5. yarn.lock 파일: Yarn은 의존성의 정확한 버전을 기록하는 yarn.lock 파일을 생성한다. 이 파일은 프로젝트의 의존성 버전에 대한 일관성을 유지하는 데 도움이 된다.

  6. 호환성: Yarn은 기존의 npm 저장소와 호환되므로, npm을 사용하는 프로젝트를 쉽게 Yarn으로 전환할 수 있다.

Yarn은 위와 같은 장점들로 많은 개발자들에게 인기를 얻었으며, 현재도 계속해서 발전하고 있다.

Yarn 설치

npm은 Node.js를 설치할 때 같이 설치해서 따로 설치하지 않아도 되지만, yarn은 따로 설치해야 한다.

npm을 이용해서 yarn을 설치해 줄 수 있다.

npm install -g yarn

lock 파일 생성

npm으로 패키지들을 설치하면 package-lock.json파일을 생성하는 것 처럼 yarn으로 패키지를 설치하면 yarn.lock잠금 파일을 생성하게 된다.

package-lock.json파일에 패키지를 최초 설치할 당시 패키지 버전들이 들어있는 것처럼 yarn.lock에도 최초 패키지 추가 시에 버전이 들어있게 된다.

그래서 yarn.lock파일이 있다면 registry에 패키지의 더 최신 버전이 있어도 yarn install로 패키지를 설치할 때 yarn.lock에 있는 버전을 사용하게 된다.

그래서 패키지 버전 문제를 최소화 할 수 있다.

Yarn 명령어

  1. yarn init
    yarn init명령어를 이용해서 package.json파일을 생성할 수 있다.

  2. yarn install
    yarn혹은 yarn install로 package.json파일에 명시된 모든 dependencies를 설치할 수 있다

  3. yarn install --force
    --force 플래그를 이용해서 강제로 모든 패키지를 추가한다.

  4. yarn add
    add 명령으로 패키지를 설치할 수 있다

    • yarn add [package]
    • yarn add [package]@[version]
    • yarn add [package]@[tag]
  5. yarn add --dev
    --dev 플래그를 사용해서 devDependencies에 패키지를 추가할 수 있다.

  6. yarn global add (yarn global remove)
    전역으로 패캐지를 설치해서 다른 프로젝트에서도 해당 패키지를 이용하려면 global을 이용하면 된다.

    • yarn global add nodemon
  7. yarn upgrade
    yarn upgrade로 모든 의존 패키지(dependencies)를 package.json에 정의한 버전의 범위에서 업데이트 할 수 있다.
    그렇지만 모든 패키지를 일괄적으로 업그레이드시키면 호환성이 문제로 conflict가 발생할 수 있다
    그래서 아래처럼 하나씩 해줄 수 있다.

$ yarn upgrade axios@^1.1.2
  1. yarn remove
    yarn remove를 이용해서 특정 패키지를 제거한다.
    이렇게 해서 package.json과 yarn.lock에서 동시에 제거가 된다

  2. yarn run [script]
    script에 지정해준 명령어를 이용해서 실행할 수 있다.

주의사항!

패키지 관리를 위해서 yarn과 npm이 두개를 하나의 프로젝트에서 혼합해서 사용하면 패키지 충돌 오류가 날 수 있기 때문에 하나의 프로젝트에는 하나의 패키지 매니저를 정해서 사용하는 것이 좋다!

profile
초보개발자. 백엔드 지망. 2024년 9월 취업 예정

0개의 댓글