node_modules/
package-a/
node_modules/
package-b/
node_modules/
package-c/node_modules/
package-a/
package-b/ ← 최상위로 끌어올림 (hoisting)
package-c/// package.json에는 package-a만 있음
{
"dependencies": {
"package-a": "^1.0.0"
}
}// 근데 이게 동작해버림 (팬텀 디펜던시)
const b = require('package-b')~/.pnpm-store/ ← 글로벌 저장소 (한 번만 저장)
v3/
files/
00/abc123... ← 파일 해시 기반으로 저장
01/def456...
my-project/
node_modules/
.pnpm/ ← 실제 패키지들 (글로벌 저장소에서 하드링크)
package-a@1.0.0/
node_modules/
package-b → .pnpm/package-b@2.0.0/ ← 심볼릭 링크
package-a → .pnpm/package-a@1.0.0/node_modules/package-a# 같은 패키지를 100개 프로젝트에서 설치해도
# 실제 파일은 글로벌 저장소에 딱 하나
~/.pnpm-store/v3/files/ ← react@18.2.0 파일들이 여기 한 번만
project-1/node_modules/.pnpm/react@18.2.0/ ← 하드링크
project-2/node_modules/.pnpm/react@18.2.0/ ← 하드링크
project-3/node_modules/.pnpm/react@18.2.0/ ← 하드링크
my-project/
.yarn/
cache/
package-a-npm-1.0.0-abc123.zip ← zip으로 압축 저장
package-b-npm-2.0.0-def456.zip
.pnp.cjs ← 패키지 위치 맵
package.json
yarn.lock// .pnp.cjs 내부 (간략화)
const packageLocatorsByLocations = new Map([
["package-a/", { name: "package-a", version: "1.0.0" }],
// ...
])git clone https://github.com/my-project
cd my-project
# yarn install 없이 바로
yarn dev # 동작함bun install # npm install과 동일한 사용법
bun add react # npm install react
bun remove react패키지 매니저 | 캐시 없음 | 캐시 있음 | lockfile만 있을 때 |
npm | 느림 | 보통 | 보통 |
Yarn v1 | 보통 | 빠름 | 빠름 |
pnpm | 빠름 | 매우 빠름 | 매우 빠름 |
Yarn Berry (PnP) | 보통 | 빠름 | 매우 빠름 |
Bun | 매우 빠름 | 압도적으로 빠름 | 압도적으로 빠름 |
패키지 매니저 | 특징 |
npm | 프로젝트마다 완전한 복사본 |
Yarn v1 | npm과 비슷, 글로벌 캐시 별도 |
pnpm | 글로벌 저장소 하드링크 → 가장 효율적 |
Yarn Berry | zip 압축으로 npm 대비 30~50% 절약 |
Bun | 글로벌 캐시 + npm 수준의 node_modules |
npm install → node_modules: ~350MB
yarn install → node_modules: ~340MB
pnpm install → node_modules: ~180MB (하드링크 + 글로벌 저장소)
yarn berry → .yarn/cache: ~70MB (zip 압축)# 패키지 설치 (전체)
npm install
yarn
pnpm install
bun install
# 패키지 추가
npm install react
yarn add react
pnpm add react
bun add react
# 개발 의존성 추가
npm install -D typescript
yarn add -D typescript
pnpm add -D typescript
bun add -d typescript
# 패키지 제거
npm uninstall react
yarn remove react
pnpm remove react
bun remove react
# 스크립트 실행
npm run dev
yarn dev
pnpm dev
bun run devnpm install -g pnpm
pnpm import # package-lock.json → pnpm-lock.yaml 변환
rm package-lock.json
pnpm install# pnpm-workspace.yaml
packages:
- 'apps/*'
- 'packages/*'# 1. pnpm 설치
npm install -g pnpm
# 2. 기존 lock 파일 변환
pnpm import
# 3. node_modules 재설치
rm -rf node_modules
pnpm install
# 4. .npmrc에 hoisting 설정 확인 (필요 시)
# .npmrc
public-hoist-pattern[]=*eslint*
public-hoist-pattern[]=*prettier*
# 5. CI 스크립트 수정 (npm → pnpm)
# .github/workflows/ci.yml
- uses: pnpm/action-setup@v2
with:
version: 8