의존성 관리 비교: npm·yarn·pnpm 선택 기준
npm, yarn, pnpm의 작동 원리와 성능, 저장소·워크스페이스 차이를 초보자 관점에서 비교한 정리
목차
개요
프로젝트 규모가 커지면 의존성 관리가 곧 생산성과 안정성의 핵심이 된다. 이 글은 npm, yarn, pnpm 세 가지 패키지 매니저를 초보자도 이해하기 쉽게 비교하고, 상황별로 어떤 도구를 선택하면 좋은지 실무 관점에서 설명한다. 또한 CI 설정과 캐시 전략, 모노레포에서의 활용법 등 실제로 유용한 사용법을 함께 다룬다.
패키지 매니저의 기초 개념
동작 방식
패키지 매니저는 의존성을 해석해 node_modules를 구성하고, 버전 충돌을 해결하며 설치 속도를 관리한다. 각 매니저의 주요 차이는 설치 방식과 락파일 처리, 디스크 사용 방식에 있다.
핵심 용어
- lockfile: 동일한 의존성 트리를 재현하기 위한 파일 (package-lock.json, yarn.lock, pnpm-lock.yaml)
- 워크스페이스: 여러 패키지를 하나의 레포에서 관리하는 구조
- 스토어/캐시: 설치된 패키지를 재사용하기 위한 중앙 저장소
npm vs yarn vs pnpm 비교
설치 속도와 디스크 효율
npm은 초기 버전보다 개선되었지만, 캐시 활용과 병렬 처리에서 yarn과 pnpm에 비해 느릴 수 있다. yarn은 병렬 설치와 캐시로 속도가 빠르며, pnpm은 중앙 저장소를 이용해 디스크 사용량을 크게 줄인다. 대량의 프로젝트를 다루면 pnpm의 효율성이 눈에 띈다.
결정성(Determinism)과 락파일
세 매니저 모두 락파일을 제공해 동일한 트리를 재현한다. 차이는 포맷과 충돌 해결 방식이다. CI나 팀환경에서는 락파일을 반드시 커밋해 의존성 불일치를 방지해야 한다.
모노레포 지원
yarn과 pnpm은 워크스페이스를 통한 모노레포 기능을 강하게 지원한다. npm도 워크스페이스를 제공하지만, pnpm은 하드링크/심볼릭 링크 기반으로 의존성 공유가 효율적이라 대형 모노레포에서 유리하다.
보안과 감사(audit)
npm과 yarn은 보안 감사 도구를 제공한다. pnpm도 npm의 레지스트리를 사용하므로 동일한 취약점 경고를 받을 수 있다. 주기적인 audit과 업데이트가 필요하다.
실무에서의 선택 기준
- 작은 프로젝트나 빠른 설정: npm으로 충분한 경우가 많음
- 팀 단위 병렬 설치와 안정적 캐시: yarn이 적합
- 대규모 레포, 다수의 패키지 공유: pnpm 권장
명령 예시
가장 기본적인 설치 및 패키지 추가 명령 예시는 다음과 같다.
npm install
npm install lodash --save
yarn install
yarn add lodash
pnpm install
pnpm add lodash
pnpm Node.js 사용법: 핵심 실무 팁
pnpm은 전역 스토어를 사용해 동일한 패키지를 한 번만 다운로드하고 심볼릭 링크로 각 프로젝트에 연결한다. 설치 속도와 디스크 효율이 장점이다. Node.js 프로젝트에서 pnpm을 도입할 때 고려할 포인트는 다음과 같다.
- pnpm 설치:
npm install -g pnpm - 기존 프로젝트 변환: 락파일을 삭제하고 pnpm install 실행
- 워크스페이스 사용: 루트에 pnpm-workspace.yaml 추가
간단한 워크스페이스 파일 예시:
packages:
- "packages/*"
- "libs/*"
CI에서의 캐시 전략
의존성 설치 최적화는 CI 비용 절감으로 직결된다. 각 매니저별 캐시 키 전략은 다음과 같다.
- npm: node_modules 캐시와 package-lock.json 해시를 조합
- yarn: yarn缓存 디렉터리(.yarn/cache)와 yarn.lock 해시
- pnpm: pnpm store 디렉터리 보존과 pnpm-lock.yaml 해시
GitHub Actions에서 pnpm 캐시를 예로 들면 다음과 같은 흐름을 사용한다.
# GitHub Actions 예시 (개념 설명)
- name: Restore pnpm store
uses: actions/cache@v3
with:
path: ~/.pnpm-store
key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}
- name: Install dependencies
run: pnpm install --frozen-lockfile
의존성 설치 최적화 Node 관점 실전 팁
- 패키지 버전은 가능한 정확 버전(exact)으로 고정해 재현성을 높인다.
- CI에서는 항상 락파일을 기반으로 --frozen-lockfile 또는 --frozen-lockfile-equivalent 옵션 사용.
- 불필요한 의존성 제거와 devDependencies/peerDependencies 구분을 철저히 한다.
- 모노레포에서는 공통 라이브러리를 루트에서 관리해 중복 설치 방지.
마무리와 권장 결론
요약하면, 단일 작은 프로젝트라면 익숙한 npm으로 충분하다. 팀 작업과 빠른 설치, 캐시를 중시하면 yarn이 실용적이다. 다수 패키지와 공간 효율, 모노레포를 고려한다면 pnpm이 더 나은 선택이 될 수 있다. 최종 선택은 팀 워크플로, CI 환경, 디스크·네트워크 제약을 고려해 결정한다.