npm과 pnpm

강개미·2025년 2월 4일
post-thumbnail

현재 진행하는 프로젝트 초기에, 한 팀원이 pnpm을 사용해봤는지 물어봤다. 주로 npm을 사용하고 있었기에 pnpmnpm의 차이도 몰랐을뿐더러 npm에 대해서도 딱히 찾아본 적이 없었다. 터미널창에 수십번도 입력한 게 npm i, npm run dev인데 자주 사용하는 패키지 매니저에 대한 것도 잘 모르면 안되겠다는 생각이 들었다. 그래서 이참에 npm이 패키지를 어떻게 관리하는지부터 pnpmnpm의 어떠한 문제점을 해결했는지 등을 알아보고자 한다.

npm

npm은 Node Package Manager로, Node.js의 기본 패키지 관리자다. npm은 Nested Dependency Structure에서 Flat Dependency Structure로 파일 구조가 바뀌었다. 기존의 파일 구조에서 발생한 중복 모듈 설치 문제를 해결하고자 3버전부터는 모든 의존성을 검토하고 의존하는 모든 패키지를 최상위 node_modules에 설치한다. 만약 이미 설치된 패키지의 다른 버전을 사용해야 한다면 필요한 패키지의 하위 node_modules에 설치한다.

이러한 Flat Dependency Structure는 불필요한 디스크 공간 차지를 줄이고 설치 속도를 향상시켰다. 그러나 이로 인해 유령 의존성과 함께 다음과 같은 문제점이 나타났다.

유령 의존성

유령 의존성은 직접적으로 설치하지 않은 패키지까지 사용하는 것을 말한다. 기존에는 다른 패키지에 의존하여 설치되었던 패키지가 Flat Dependency Structure로 인해 최상위 node_modules까지 올라오게 되면서 package.json에 명시하지 않은 패키지까지 설치되는 문제가 발생하였다.

용량 및 속도

npm은 프로젝트마다 의존성이 개별로 설치된다. 이로 인해 디스크에 거대한 용량이 차지되기 일수다. 또한, 깊고 복잡한 패키지 구조로 인해 의존성 분석이 오래 걸리고, 의존성 해결 과정에서 결정된 순서에 따라 패키지들을 순차적으로 설치하기 때문에 속도가 느리다.

pnpm

pnpm은 Performant Node Package Manager로, 기존 npm의 단점을 보완하기 위해 탄생한 패키지 매니저다. pnpm은 패키지를 전역 store에 설치하고 하드 링크심볼릭 링크를 사용하여 의존성 중첩 구조를 가진다. pnpm의 구체적인 원리를 설명하기 전에 하드 링크와 심볼릭 링크에 대해 알아보자.

하드 링크

하드 링크는 파일 시스템 내에서 동일한 파일 내용을 가리키는 두 개 이상의 파일을 의미한다. 하나의 파일에 대해 두 개의 하드 링크가 있을 때, 하나의 하드 링크를 삭제해도 원본 파일은 삭제되지 않기 때문에 모든 하드 링크가 삭제되기 전까지는 파일 데이터가 파일 시스템에 남아있다.

심볼릭 링크

심볼릭 링크는 특정 파일이나 디렉토리를 가리키는 파일을 의미한다. 심볼릭 링크는 원본 파일의 경로를 저장하고, 원본 파일이 이동하거나 삭제되면 더이상 유효하지 않는다.

원리

pnpm intall 명령어를 입력하면 전역 pnpm store에 패키지들이 해시 값으로 저장된다. node_modules 아래에 생긴 패키지들은 node_modules/.pnpm에 심볼릭 링크를 참조하고 있다. 즉, 실재하는 것이 아닌 참조되고 있을 뿐이다. node_modules/.pnpm 아래에는 전역으로 하드 링크가 걸린 모든 패키지들이 존재한다.

이처럼 각 프로젝트의 node_modules에는 실제 파일이 복제되는 것이 아니라 전역 store의 파일들을 참조하기 때문에 디스크 공간과 설치 시간을 절약할 수 있다.또한, 모든 의존성 트리가 완벽한 중첩 구조로 이루어져 있기 때문에 직접적으로 의존하는 패키지만 참조하여 유령 의존성 현상을 해결한다.

yarn

그렇다면 yarn은 어떤 원리를 갖고 있을까?

내 첫 프로젝트는 yarn으로 패키지 관리를 진행했었다. npmpnpm을 공부하면서 자연스레 그때 사용했던 yarn은 어떤 원리를 가졌는지까지 정리하려 했으나... Hadoop을 비롯해서 공부해야 할 내용이 많은 것 같아 간단하게만 찾아봤다.

yarn은 JavaScript 패키지 매니저로, package.json 파일을 통해 해당 프로젝트가 의존하는 모든 패키지를 구분하고 package.json에 있는 dependencies 필드를 기반으로 패키지를 설치한다.

yarn은 병렬 다운로드와 캐싱 기능을 도입하여 npm보다 설치 속도가 빠르며, yarn.lock 파일을 사용하여 의존성을 고정시킴으로써 모든 개발 환경에 있는 패키지 버전을 유지할 수 있도록 하였다.

참고

📚 지금 당장 pnpm으로 넘어가야 하는 이유
📚 pnpm 파헤치기
📚 pnpm
📚 yarn이란 무엇인가?

profile
프론트엔드 개발자

0개의 댓글