pnpm(Performant npm)은 npm의 드롭인(drop-in) 대체제로, 두 가지 핵심 아이디어를 갖고 있어요 : 각 패키지의 복사본 하나만 보관하는 디스크 전역 store와, 팬텀 의존성을 방지하는 엄격한 해결 방식.
pnpm이 공간을 많이 절약하는 이유
npm install react를 실행하면 npm이 파일을 your-project/node_modules/react/에 복사해요. React를 사용하는 프로젝트가 열 개라면, 디스크에 동일한 복사본이 열 개 생겨요.
pnpm은 다르게 동작해요:
- React를 전역 store(
~/.local/share/pnpm/store, Windows는%LOCALAPPDATA%\pnpm\store)에 한 번만 다운로드해요. - 각 프로젝트의
node_modules/react/는 store 파일을 가리키는 하드링크예요. 물리적 파일 하나로 열 개의 프로젝트가 접근해요.
구체적으로 : React 프로젝트가 열 개인 머신에서 npm은 프로젝트당 ~400MB를 사용해요. pnpm은 프로젝트 수에 관계없이 공유 store ~40MB만 사용해요.
pnpm 설치하기
npm으로(최초 한 번):
corepack으로(Node v16부터 포함):
확인:
자주 쓰는 명령어
기존 프로젝트의 모든 의존성 설치:
패키지 추가:
개발 의존성 추가:
package.json에 정의된 스크립트 실행:
자주 쓰는 스크립트 단축키(run 없이):
전역 설치 없이 일회성 명령어 실행:
모든 의존성 업데이트:
패키지 제거:
엄격한 해결 : 팬텀 의존성 없음
pnpm은 평탄화되지 않은 node_modules/ 구조를 만들어요. 각 패키지는 자신의 선언된 의존성만 볼 수 있어요. package.json에 lodash를 명시적으로 추가하지 않으면 코드에서 lodash에 접근할 수 없어요.
제한적으로 느껴질 수 있지만, 이건 안전망이에요 : 빌드가 재현 가능하고 의존성의 과도적 의존성에 의존하지 않아요.
pnpm과 모노레포
pnpm은 세 가지 패키지 매니저 중에서 모노레포 지원이 가장 뛰어나요. 루트에 pnpm-workspace.yaml 파일 하나로 여러 패키지를 선언할 수 있어요:
packages:
- "packages/*"
- "apps/*"워크스페이스의 패키지들은 버전으로 workspace:*를 사용해서 서로 참조할 수 있어요:
{
"dependencies": {
"@my-project/shared": "workspace:*"
}
}