본문 바로가기
프론트엔드/개발 기초 지식

[패키지 매니저] PNPM

by 학습하는 청년 2024. 12. 22.

최종 수정 : 24.12.21

PNPM

PNPM은 2016년에 등장했다(Yarn과 동일). NPM과 Yarn의 비효율적인 패키지 관리 방식을 개선하기 위해 만들어졌다.

 

NPM과 Yarn의 문제점과 그에 따른 PNPM의 해결방식

1. 디스크 공간 낭비

기존 패키지 매니저들은 각 프로젝트마다 node_modules 디렉토리에 모든 의존성을 개별적으로 설치했다. 10개의 프로젝트를 진행한다면, 동일한 라이브러리들이 10개가 중복으로 설치되어 그만큼 디스크 공간 낭비를 초래했다.

 

-> PNPM은 content-addressable 저장소를 도입했다. 모든 패키지를 전역 저장소(.pnpm/store)에 단 한 번만 저장하고, 각 프로젝트에서는 심링크를 통해 이를 참조하는 방식을 사용한다. 예를 들어 React 18.2.0 버전은 전역 저장소에 한 번만 저장되고, 이를 사용하는 모든 프로젝트는 심링크를 통해 같은 파일을 참조한다. 이를 통해 디스크 공간 사용량을 획기적으로 줄일 수 있게 됐다.

 

2. 비효율적인 설치 과정

기존 방식에서는 패키지를 설치할 때마다 npm registry에서 패키지를 다운로드하고, 압축을 해제하고, node_modules에 복사하는 과정을 반복해야 했다. 이는 설치 시간을 크게 증가시키는 원인이었다.

 

-> PNPM은 하드 링크와 심링크를 조합한 효율적인 설치 방식을 도입했다. 한 번 설치한 패키지는 전역 저장소에 캐시되어, 다른 프로젝트에서 동일한 패키지를 설치할 때는 단순히 심링크만 생성하면 된다. 이로 인해 설치 시간이 크게 단축되었으며, 특히 CI/CD 환경에서 큰 성능 향상을 보여준다.

 

3. 유령 의존성 문제

NPM과 Yarn은 평면적인 의존성 구조로 인해, package.json에 명시하지 않은 패키지도 실제로 사용할 수 있었다. 이는 예상치 못한 오류의 원인이 되기도 했다.

 

-> PNPM은 엄격한 심볼릭 링크 구조를 도입했다. node_modules 디렉토리 구조를 완전히 재설계하여, 각 패키지가 자신의 package.json에 명시된 의존성에만 접근할 수 있도록 제한했다. 이를 통해 유령 의존성 문제를 원천적으로 차단하고, 의존성 관계를 더욱 명확하게 만들었다.

 

4. 의존성 지옥

복잡한 프로젝트에서는 서로 다른 버전의 같은 패키지가 필요한 경우가 많았는데, 이는 의존성 충돌을 일으켰다.

 

-> PNPM은 각 패키지의 의존성을 독립적으로 관리하여 서로 다른 버전의 같은 패키지가 필요한 경우, 각각의 전역 저장소에 저장하고 정확한 버전을 참조할 수 있도록 했다. 이를 통해 버전 충돌 없이 여러 버전의 패키지를 동시에 사용할 수 있게 됐다.

 

5. CI/CD 환경에서의 성능 문제

지속적 통합/배포 환경에서는 매번 새로운 환경에서 패키지를 설치해야 했고, 이는 빌드 시간을 크게 증가시켰다.

 

-> PNPM의 전역 저장소와 심링크 방식은 CI/CD 환경에서도 큰 효과를 발휘한다. 캐시를 효율적으로 활용할 수 있고, 실제 파일 복사가 최소화되어 빌드 시간을 크게 단축할 수 있다. 또한 store 디렉토리를 캐시로 활용하여 CI/CD 파이프라인의 성능을 더욱 최적화할 수 있다.

 

6. 부정확한 의존성 관리

기존 패키지 매니저들은 의존성 트리를 평면화하는 과정에서 예측하기 어려운 결과를 만들어냈다. "내 컴퓨터에서는 되는데..." 라는 이슈들을 발생시켰다.

 

-> PNPM은 정확한 의존성 트리 구조를 유지한다. 각 패키지는 자신의 명시적인 의존성만 접근할 수 있으며, 이는 package.json을 통해 명확하게 관리된다. 이를 통해 모든 환경에서 일관된 의존성 구조를 보장할 수 있게 됐다.


이러한 해결 방식들은 특히 대규모 프로젝트나 모노레포 환경에서 큰 효과를 발휘한다.

댓글