๐Ÿ”„ npm โ†’ pnpm ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ โ€” ์•ˆ์ „ํ•˜๊ฒŒ, ์™„์ „ํ•˜๊ฒŒ

2026๋…„ 3์›” 20์ผ ์ˆ˜์ •๋จ

๐Ÿ“‹ ๊ฐœ์š”

๊ธฐ์กด npm/Yarn ํ”„๋กœ์ ํŠธ๋ฅผ pnpm ์œผ๋กœ ์ „ํ™˜ํ•˜๋Š” ๋‹จ๊ณ„๋ณ„ ๋ฃจํ‹ด, ํ”ํ•œ ํ•จ์ •๊ณผ ํ•ด๊ฒฐ์ฑ…, ํŒ€ ์ „์ฒด ์˜จ๋ณด๋”ฉ ์ฒดํฌ๋ฆฌ์ŠคํŠธ๊นŒ์ง€

07. npm โ†’ pnpm ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜

๐Ÿ“‹ ๋ชฉ์ฐจ

  1. pnpm ์˜ ์•Œ๋ ค์ง„ ์ œํ•œ์‚ฌํ•ญ
  2. ์ด์ •๋ฆฌ
  3. ๋งˆ๋ฌด๋ฆฌ ํ€ด์ฆˆ
  4. ์˜์ฒ ์ด์˜ ํ‡ด๊ทผ ์ผ๊ธฐ
  5. ๋” ์•Œ์•„๋ณด๊ธฐ

๐Ÿ“Œ ์ด ๋ฌธ์„œ๋ฅผ ์ฝ๊ธฐ ์ „์—

โฑ๏ธ ์˜ˆ์ƒ ์ฝ๊ธฐ ์‹œ๊ฐ„: ์•ฝ 30๋ถ„(์ „์ฒด) / ํ•ต์‹ฌ ํŒŒํŠธ๋งŒ: 15๋ถ„

๐Ÿ—บ๏ธ ์ด ๋ฌธ์„œ์˜ ํ๋ฆ„

[์ „ํ™˜ ์ „ ์ฒดํฌ๋ฆฌ์ŠคํŠธ] โ†’ [๋‹จ๊ณ„๋ณ„ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜] โ†’ [ํ•จ์ • ํ•ด๊ฒฐ] โ†’ [ํŒ€ ์˜จ๋ณด๋”ฉ] โ†’ [์ œํ•œ์‚ฌํ•ญ ์ธ์‹]

๐ŸŽฏ ์ด ๋ฌธ์„œ๋ฅผ ๋‹ค ์ฝ์œผ๋ฉด ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ

  • npm/Yarn ํ”„๋กœ์ ํŠธ๋ฅผ pnpm ์œผ๋กœ ์•ˆ์ „ํ•˜๊ฒŒ ์ „ํ™˜ํ•˜๋Š” 7๋‹จ๊ณ„ ๋ฃจํ‹ด์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค
  • ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํ›„ ๋ฐœ์ƒํ•˜๋Š” ํ”ํ•œ ์—๋Ÿฌ๋ฅผ ์Šค์Šค๋กœ ์ง„๋‹จํ•˜๊ณ  ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค
  • CI/CD, GitHub Actions, Docker ๋ฅผ pnpm ๊ธฐ์ค€์œผ๋กœ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ๋‹ค
  • pnpm ์˜ ์•Œ๋ ค์ง„ ์ œํ•œ์‚ฌํ•ญ์„ ํŒ€์—๊ฒŒ ์‚ฌ์ „์— ์•ˆ๋‚ดํ•  ์ˆ˜ ์žˆ๋‹ค

๐Ÿ—บ๏ธ ์ด ๋ฌธ์„œ์˜ ๋ฐฐ๊ฒฝ ์„ธ๊ณ„๊ด€: '์˜์ˆ˜๋„ค ์ปค๋ฎค๋‹ˆํ‹ฐ'

๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์ด ๋ง‰๋ง‰ํ•œ ์˜์ฒ ์ด์™€ ์ˆœ์„œ๋Œ€๋กœ ํ•˜๋ผ๋Š” ์˜ํ˜ธ
  • ๐Ÿฃ ์˜์ฒ  ( ์‹ ์ž… ): "์˜ํ˜ธ ๋‹˜, ๋“œ๋””์–ด ์˜์ˆ˜ ๋‹˜์ด pnpm ์ „ํ™˜ ์Šน์ธํ•ด์ฃผ์…จ์–ด์š”! ๊ทผ๋ฐ ๋ง‰์ƒ ์‹œ์ž‘ํ•˜๋ ค๋‹ˆ ์–ด๋””์„œ๋ถ€ํ„ฐ ํ•ด์•ผ ํ• ์ง€ ๋ชจ๋ฅด๊ฒ ์–ด์š”. ๊ทธ๋ƒฅ npm install ๋Œ€์‹  pnpm install ํ•˜๋ฉด ๋˜๋Š” ๊ฑด๊ฐ€์š”? ๊ธฐ์กด package-lock.json ์€ ์–ด๋–ป๊ฒŒ ํ•˜๊ณ , .github/workflows ๋„ ๋ฐ”๊ฟ”์•ผ ํ•˜๋‚˜์š”? CI ์—์„œ ๋ฐฐํฌ ํŒŒ์ดํ”„๋ผ์ธ ๋„์ค‘์— ์‹คํŒจํ•˜๋ฉด ๋˜๋Œ๋ฆด ์ˆ˜ ์žˆ๋‚˜์š”?"
  • ๐Ÿฆ ์˜ํ˜ธ ( ๋ฆฌ๋“œ ): "๊ธ‰ํ•˜๊ฒŒ ํ•˜๋ฉด ๊ผญ ๋ญ”๊ฐ€ ๋น ์ ธ์š”. ์ˆœ์„œ๊ฐ€ ์ค‘์š”ํ•ด์š”. pnpm import ๋กœ ๊ธฐ์กด lock ํŒŒ์ผ์„ ๋ณ€ํ™˜ํ•˜๊ณ , .npmrc ์—์„œ hoisting ์„ค์ •์„ ์ ๊ฒ€ํ•˜๊ณ , ๋กœ์ปฌ์—์„œ dev/build/test ๋‹ค ํ†ต๊ณผํ•œ ๋’ค์— CI ์ˆ˜์ •ํ•ด์•ผ ํ•ด์š”. ํŠนํžˆ GitHub Actions ์›Œํฌํ”Œ๋กœ์šฐ ํŒŒ์ผ์€ ๋ธŒ๋žœ์น˜๋ฅผ ๋”ฐ๋กœ ๋งŒ๋“ค์–ด์„œ PR ๋กœ ๊ฒ€์ฆํ•˜๊ณ  ๋จธ์ง€ํ•˜๋Š” ๊ฒŒ ์•ˆ์ „ํ•ด์š”. ์„œ๋‘๋ฅด์ง€ ๋ง๊ณ  ์ฒดํฌ๋ฆฌ์ŠคํŠธ ํ•˜๋‚˜์”ฉ ๋ฐŸ์•„๊ฐ€์„ธ์š”."

๐Ÿค” ์™œ ์•Œ์•„์•ผ ํ•˜๋Š”๊ฐ€

pnpm ์€ npm ๊ณผ ๊ฐœ๋…์ ์œผ๋กœ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ๋‹จ์ˆœํžˆ ๋ช…๋ น์–ด๋งŒ ๋ฐ”๊พธ๋ฉด ๋œ๋‹ค๋Š” ์ƒ๊ฐ์€ ํ•จ์ •์ด๋‹ค.

์‹ค์ œ๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๋„์ค‘ ์ž์ฃผ ๊ฒช๋Š” ์ƒํ™ฉ:

โœ… ๋กœ์ปฌ์—์„œ๋Š” ์ž˜ ๋˜๋Š”๋ฐ CI ์—์„œ ์‹คํŒจ
โœ… ๋นŒ๋“œ๋Š” ๋˜๋Š”๋ฐ ESLint ๊ฐ€ ์•ˆ ๋จ
โœ… ๊ฐœ๋ฐœ ์„œ๋ฒ„๋Š” ๋œจ๋Š”๋ฐ ํŠน์ • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ import ์—๋Ÿฌ
โœ… ํŒ€์› A ๋Š” ๋˜๋Š”๋ฐ ํŒ€์› B ๋Š” ์•ˆ ๋จ
โœ… Docker ๋นŒ๋“œ๊ฐ€ ๊ฐ‘์ž๊ธฐ ํ›จ์”ฌ ๋А๋ ค์ง

์ด ๋ชจ๋“  ์ƒํ™ฉ์€ ์ฒด๊ณ„์ ์ธ ์ˆœ์„œ ๋กœ ์ง„ํ–‰ํ•˜๋ฉด ๋Œ€๋ถ€๋ถ„ ์˜ˆ๋ฐฉํ•  ์ˆ˜ ์žˆ๋‹ค.


โœ… ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์ „ ์ฒดํฌ๋ฆฌ์ŠคํŠธ

๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์‹œ์ž‘ ์ „, ํ˜„์žฌ ํ”„๋กœ์ ํŠธ ์ƒํƒœ๋ฅผ ์ ๊ฒ€ํ•˜๋ผ.

# 1. ํ˜„์žฌ ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ € ํ™•์ธ
cat package.json | grep packageManager
ls -la | grep -E "package-lock|yarn.lock|pnpm-lock"
 
# 2. ์‚ฌ์šฉ ์ค‘์ธ npm scripts ํ™•์ธ (postinstall ์ด ์žˆ๋Š”์ง€)
cat package.json | grep -A 20 '"scripts"'
 
# 3. .npmrc ๊ฐ€ ์žˆ์œผ๋ฉด ๋‚ด์šฉ ํ™•์ธ
cat .npmrc 2>/dev/null
 
# 4. CI/CD ํŒŒ์ผ ๋ชฉ๋ก ํ™•์ธ
ls .github/workflows/

์ฒดํฌ๋ฆฌ์ŠคํŠธ:

ํ•ญ๋ชฉํ™•์ธ ๋ฐฉ๋ฒ•์ฃผ์˜์‚ฌํ•ญ
Node.js ๋ฒ„์ „.nvmrc ๋˜๋Š” package.json enginespnpm 9 ์€ Node.js 18.12+ ํ•„์š”
postinstall ์Šคํฌ๋ฆฝํŠธpackage.json scriptsPrisma, Husky ๋“ฑ โ€” pnpm ์—์„œ๋„ ๋™์ž‘ ํ™•์ธ ํ•„์š”
private registry.npmrc์Šค์ฝ”ํ”„๋ณ„ registry ์„ค์ • pnpm ๋„ ์ง€์›
CI ํ”Œ๋žซํผ.github/, .circleci/ ๋“ฑpnpm ์„ค์น˜ ๋‹จ๊ณ„ ์ถ”๊ฐ€ ํ•„์š”
DockerDockerfilepnpm ์„ค์น˜ + store ์บ์‹œ ์ „๋žต
Dependabot.github/dependabot.ymlpackage-ecosystem: "npm" ์œผ๋กœ๋„ pnpm ์ง€์›

๐Ÿชœ ๋‹จ๊ณ„๋ณ„ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๋ฃจํ‹ด

Step 1: pnpm ์„ค์น˜

# Corepack ์œผ๋กœ ์„ค์น˜ (๊ถŒ์žฅ)
corepack enable
corepack prepare pnpm@latest --activate
 
# ๋˜๋Š” npm ์œผ๋กœ
npm install -g pnpm
 
# ๋ฒ„์ „ ํ™•์ธ
pnpm --version

Step 2: lock ํŒŒ์ผ ๋ณ€ํ™˜

# npm โ†’ pnpm: package-lock.json ์„ pnpm-lock.yaml ๋กœ ๋ณ€ํ™˜
pnpm import
 
# yarn.lock โ†’ pnpm-lock.yaml
pnpm import
 
# ๋ณ€ํ™˜ ํ›„ ํ™•์ธ
ls pnpm-lock.yaml  # ์ƒ์„ฑ๋จ

์ฃผ์˜: pnpm import ๋Š” ๊ธฐ์กด lock ํŒŒ์ผ์„ ์ฐธ๊ณ ํ•ด์„œ pnpm-lock.yaml ์„ ์ƒ์„ฑํ•˜์ง€๋งŒ, 100% ๋™์ผํ•œ ๋ฒ„์ „์ด ๋ณด์žฅ๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค. ํŠนํžˆ ๊ฐ„์ ‘ ์˜์กด์„ฑ ๋ฒ„์ „์ด ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, Step 4 ์—์„œ ๋ฐ˜๋“œ์‹œ ํ…Œ์ŠคํŠธ๋กœ ๊ฒ€์ฆํ•œ๋‹ค.

Step 3: ๊ธฐ์กด lock ํŒŒ์ผ ๋ฐ node_modules ์ •๋ฆฌ

# ๊ธฐ์กด ํŒŒ์ผ ์ œ๊ฑฐ
rm -rf node_modules
rm package-lock.json  # npm ์ด์—ˆ๋‹ค๋ฉด
# rm yarn.lock         # yarn ์ด์—ˆ๋‹ค๋ฉด
 
# ๐Ÿฆ .gitignore ์— pnpm-lock.yaml ์ด ์—†๋Š”์ง€ ํ™•์ธ (์žˆ์œผ๋ฉด ์ œ๊ฑฐ)
grep "pnpm-lock" .gitignore

Step 4: .npmrc ์„ค์ •

# .npmrc (์‹ ๊ทœ๋กœ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜, ๊ธฐ์กด ํŒŒ์ผ ๋งจ ์œ„์— ์ด ๋‚ด์šฉ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค)
 
# ๐Ÿฆ [์ดˆํ•ต์‹ฌ] Next.js ํ”„๋กœ์ ํŠธ ํ•„์ˆ˜ ์„ค์ • (ํ˜ธ์ด์ŠคํŒ… ํ—ˆ์šฉ)
# ์›๋ž˜ pnpm์€ ์ˆจ๊ฒจ์ง„ ์˜์กด์„ฑ์„ ์ ˆ๋Œ€ ํ—ˆ์šฉํ•˜์ง€ ์•Š์ง€๋งŒ, ์•„๋ž˜ ์ ํžŒ ๋…€์„๋“ค์€ ์˜ˆ์™ธ๋กœ ์ณ์ค๋‹ˆ๋‹ค.
# ์ด๊ฑธ ์•ˆ ์ ์–ด์ฃผ๋ฉด ESLint๋‚˜ Tailwind๊ฐ€ "๋ชจ๋“ˆ์„ ์ฐพ์„ ์ˆ˜ ์—†๋‹ค"๊ณ  ํŒŒ์—…์„ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค.
public-hoist-pattern[]=*types*
public-hoist-pattern[]=*eslint*
public-hoist-pattern[]=prettier
public-hoist-pattern[]=tailwindcss
public-hoist-pattern[]=postcss
public-hoist-pattern[]=autoprefixer
 
# ๐Ÿฆ [์•ˆ์ „ ์žฅ์น˜] package.json์— ์ ํžŒ Node/pnpm ๋ฒ„์ „์ด ์•„๋‹ˆ๋ฉด ์„ค์น˜ ์ž์ฒด๋ฅผ ํŠ•๊ฒจ๋ƒ…๋‹ˆ๋‹ค.
engine-strict=true

Step 5: pnpm install & ๊ฒ€์ฆ

# ์ƒˆ๋กœ ์„ค์น˜
pnpm install
 
# ๋กœ์ปฌ ๊ฒ€์ฆ (์ด ์„ธ ๊ฐ€์ง€ ๋ชจ๋‘ ํ†ต๊ณผํ•ด์•ผ ๋‹ค์Œ ๋‹จ๊ณ„๋กœ)
pnpm dev           # ๊ฐœ๋ฐœ ์„œ๋ฒ„ ์ •์ƒ ๋™์ž‘ ํ™•์ธ
pnpm build         # ํ”„๋กœ๋•์…˜ ๋นŒ๋“œ ์„ฑ๊ณต ํ™•์ธ
pnpm test          # ํ…Œ์ŠคํŠธ ํ†ต๊ณผ ํ™•์ธ
pnpm lint          # lint ์—๋Ÿฌ ์—†์Œ ํ™•์ธ
pnpm typecheck     # TypeScript ์—๋Ÿฌ ์—†์Œ ํ™•์ธ

Step 6: package.json ์—…๋ฐ์ดํŠธ

// package.json
{
  "packageManager": "pnpm@9.15.0",
  "engines": {
    "node": ">=20.0.0",
    "pnpm": ">=9.0.0"
  },
  "scripts": {
    // npm ci โ†’ pnpm install --frozen-lockfile
    // npx โ†’ pnpm dlx
    "postinstall": "prisma generate"  // ๊ทธ๋Œ€๋กœ ์œ ์ง€ (pnpm ๋„ ์‹คํ–‰ํ•จ)
  }
}

Step 7: git ์ปค๋ฐ‹

git add pnpm-lock.yaml .npmrc package.json
git rm package-lock.json  # ๋˜๋Š” yarn.lock
git commit -m "chore: npm โ†’ pnpm ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜
 
- package-lock.json โ†’ pnpm-lock.yaml ๋ณ€ํ™˜ (pnpm import)
- .npmrc ์ถ”๊ฐ€ (public-hoist-pattern ์„ค์ •)
- package.json ์— packageManager ํ•„๋“œ ์ถ”๊ฐ€
- engines ํ•„๋“œ ์—…๋ฐ์ดํŠธ (node>=20, pnpm>=9)"

๐Ÿšง ํ”ํ•œ ํ•จ์ •๊ณผ ํ•ด๊ฒฐ์ฑ…

ํ•จ์ • 1: ESLint / TypeScript ๊ด€๋ จ ์—๋Ÿฌ

Error: Cannot find module 'eslint'
Error: Cannot find module '@types/react'

ํ•ด๊ฒฐ:

# .npmrc ์— ํ˜ธ์ด์ŠคํŒ… ํŒจํ„ด ์ถ”๊ฐ€
public-hoist-pattern[]=*types*
public-hoist-pattern[]=*eslint*
pnpm install  # ์žฌ์„ค์น˜ํ•˜๋ฉด ์ ์šฉ๋จ

ํ•จ์ • 2: Prisma generate ์‹คํŒจ

Error: @prisma/client did not initialize yet.
Please run "prisma generate"

ํ•ด๊ฒฐ:

// package.json
{
  "scripts": {
    "postinstall": "prisma generate"
  }
}

ํ•จ์ • 3: Husky hooks ๊ฐ€ ๋™์ž‘ํ•˜์ง€ ์•Š์Œ

.husky/pre-commit not found

ํ•ด๊ฒฐ:

# husky ์žฌ์ดˆ๊ธฐํ™”
pnpm dlx husky install
 
# ๋˜๋Š” package.json ์˜ prepare ์Šคํฌ๋ฆฝํŠธ
{
  "scripts": {
    "prepare": "husky"
  }
}

ํ•จ์ • 4: ํŒฌํ…€ ์˜์กด์„ฑ์œผ๋กœ ์ธํ•œ ๋นŒ๋“œ ์—๋Ÿฌ

Error: Cannot find module 'some-package'
# package.json ์— ์—†๋Š” ํŒจํ‚ค์ง€๋ฅผ ์ง์ ‘ import ํ•˜๊ณ  ์žˆ์—ˆ์Œ

ํ•ด๊ฒฐ:

# ์–ด๋–ค ํŒจํ‚ค์ง€์ธ์ง€ ํ™•์ธ
pnpm why some-package
 
# package.json ์— ๋ช…์‹œ์ ์œผ๋กœ ์ถ”๊ฐ€
pnpm add some-package

์ด ์—๋Ÿฌ๋Š” npm ์—์„  ํŒฌํ…€ ์˜์กด์„ฑ์œผ๋กœ ๋™์ž‘ํ•˜๋‹ค๊ฐ€ pnpm ์—์„œ ์ •์ƒ์ ์œผ๋กœ ์ฐจ๋‹จ๋œ ์ผ€์ด์Šค๋‹ค. ์ˆ˜์ •์ด ํ•„์š”ํ•œ ์ฝ”๋“œ ํ’ˆ์งˆ ๋ฌธ์ œ ์ด๋ฏ€๋กœ ๋ฐ˜๋“œ์‹œ package.json ์— ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค.

ํ•จ์ • 5: ํŠน์ • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์‹ฌ๋งํฌ๋ฅผ ๋”ฐ๋ผ๊ฐ€์ง€ ๋ชปํ•จ

Error: ENOENT: no such file or directory, scandir '.../node_modules/...'

ํ•ด๊ฒฐ (๋‹จ๊ณ„์  ์ ‘๊ทผ):

# 1๋‹จ๊ณ„: ํ•ด๋‹น ํŒจํ‚ค์ง€๋งŒ ์„ ํƒ์ ์œผ๋กœ ํ˜ธ์ด์ŠคํŒ…
public-hoist-pattern[]=๋ฌธ์ œ๊ฐ€๋˜๋Š”ํŒจํ‚ค์ง€๋ช…
 
# 2๋‹จ๊ณ„: ๊ทธ๋ž˜๋„ ์•ˆ ๋˜๋ฉด nodeLinker ๋ฅผ hoisted ๋กœ ๋ณ€๊ฒฝ
# pnpm-workspace.yaml ๋˜๋Š” .npmrc
node-linker=hoisted

ํ•จ์ • 6: Docker ๋นŒ๋“œ ์‹œ corepack ๋ฏธ์„ค์น˜

# โŒ ๋ฌธ์ œ ์žˆ๋Š” Dockerfile
FROM node:20-slim
RUN npm install -g pnpm  # ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ฒ„์ „ ๋ถˆ์ผ์น˜ ๊ฐ€๋Šฅ
 
# โœ… ์˜ฌ๋ฐ”๋ฅธ ๋ฐฉ๋ฒ•
FROM node:20-slim
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable
# package.json ์˜ packageManager ๋ฒ„์ „์œผ๋กœ ์ž๋™ ํ™œ์„ฑํ™”๋จ

ํ•จ์ • 7: pnpm-lock.yaml ์ด .gitignore ์— ํฌํ•จ๋œ ๊ฒฝ์šฐ

# .gitignore ํ™•์ธ
grep "pnpm-lock" .gitignore
 
# ์žˆ๋‹ค๋ฉด ์ œ๊ฑฐ
# pnpm-lock.yaml ์€ ๋ฐ˜๋“œ์‹œ git ์— ์ปค๋ฐ‹ํ•ด์•ผ ํ•จ
# (npm ์˜ package-lock.json ๊ณผ ๋™์ผํ•œ ์—ญํ• )

๐Ÿ‘ฅ ํŒ€ ์˜จ๋ณด๋”ฉ & CI/CD ์ „ํ™˜

ํŒ€์› ์˜จ๋ณด๋”ฉ ์•ˆ๋‚ด๋ฌธ ํ…œํ”Œ๋ฆฟ

## pnpm ์œผ๋กœ ์ „ํ™˜๋˜์—ˆ์Šต๋‹ˆ๋‹ค ๐ŸŽ‰
 
### ์„ค์น˜
\`\`\`bash
corepack enable
pnpm --version  # 9.x.x ๊ฐ€ ํ‘œ์‹œ๋˜๋ฉด ์™„๋ฃŒ
\`\`\`
 
### ๊ธฐ์กด ๋ช…๋ น์–ด โ†’ ์ƒˆ ๋ช…๋ น์–ด
| ๊ธฐ์กด | ๋ณ€๊ฒฝ |
|------|------|
| npm install | pnpm install |
| npm install ํŒจํ‚ค์ง€ | pnpm add ํŒจํ‚ค์ง€ |
| npm install -D ํŒจํ‚ค์ง€ | pnpm add -D ํŒจํ‚ค์ง€ |
| npm uninstall ํŒจํ‚ค์ง€ | pnpm remove ํŒจํ‚ค์ง€ |
| npm run dev | pnpm dev |
| npx create-next-app | pnpm dlx create-next-app |
| npm ci | pnpm install --frozen-lockfile |
 
### ์ฃผ์˜์‚ฌํ•ญ
- \`package-lock.json\` ์€ ๋” ์ด์ƒ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„์š”
- \`pnpm-lock.yaml\` ์ด ์ƒˆ๋กœ์šด lock ํŒŒ์ผ์ด์—์š” (์ปค๋ฐ‹ ํ•„์ˆ˜)
- \`node_modules\` ๊ตฌ์กฐ๊ฐ€ ๋‹ฌ๋ผ ๋ณด์—ฌ๋„ ์ •์ƒ์ด์—์š”

GitHub Actions ์ „ํ™˜

# ๐Ÿ’ก CI ํŒŒ์ดํ”„๋ผ์ธ (GitHub Actions) ์ „ํ™˜ ์ „ํ›„ ๋น„๊ต
 
# โŒ ๋ณ€๊ฒฝ ์ „ (npm ์‹œ์ ˆ) โŒ
- name: Install
  run: npm ci # ํŒจํ‚ค์ง€ ์„ค์น˜์—๋งŒ 2~3๋ถ„์ด ๊ฑธ๋ฆฌ๋˜ ์‹œ์ ˆ
 
# --------------------------------------------------
 
# โœ… ๋ณ€๊ฒฝ ํ›„ (pnpm ๋„์ž…) โœ…
# 1๏ธโƒฃ ์ปดํ“จํ„ฐ์— pnpm์„ ๊น”์•„์ฃผ๋Š” ๋งˆ๋ฒ•์˜ Action
- name: Setup pnpm
  uses: pnpm/action-setup@v4
  # (์—ฌ๊ธฐ์— version: 9 ๋ผ๊ณ  ์“ฐ์ง€ ์•Š์•„๋„ package.json์˜ packageManager๋ฅผ ์•Œ์•„์„œ ์ฝ์Šต๋‹ˆ๋‹ค!)
 
- name: Setup Node.js
  uses: actions/setup-node@v4
  with:
    node-version: 20
    # 2๏ธโƒฃ [ํ•ต์‹ฌ] ์ด๊ฑฐ ํ•œ ์ค„๋งŒ ์“ฐ๋ฉด ๋! pnpm ๊ธ€๋กœ๋ฒŒ ์ €์žฅ์†Œ๊ฐ€ ํ†ต์งธ๋กœ ์บ์‹ฑ๋ฉ๋‹ˆ๋‹ค.
    cache: 'pnpm'               
 
- name: Install
  # 3๏ธโƒฃ ๋ฐฐํฌ ์‹œ์ ์—๋Š” ๋ฌด์กฐ๊ฑด lock ํŒŒ์ผ์„ ์‹ ๋ขฐํ•ด์•ผ ํ•˜๋ฏ€๋กœ --frozen-lockfile์„ ์”๋‹ˆ๋‹ค. (npm ci ์™€ ๋˜‘๊ฐ™์€ ์—ญํ• )
  # ์œ„์—์„œ ์บ์‹œ๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ์ ์šฉ๋˜์—ˆ๋‹ค๋ฉด ์„ค์น˜๊ฐ€ 15์ดˆ ์ปท์œผ๋กœ ๋๋‚ฉ๋‹ˆ๋‹ค!
  run: pnpm install --frozen-lockfile

Dependabot ์„ค์ • (๋ณ€๊ฒฝ ์—†์Œ)

# .github/dependabot.yml
# npm ecosystem ์ด pnpm-lock.yaml ๋„ ์ง€์›ํ•จ โ€” ๋ณ€๊ฒฝ ๋ถˆํ•„์š”
version: 2
updates:
  - package-ecosystem: "npm"   # npm ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉ
    directory: "/"
    schedule:
      interval: "weekly"

๐Ÿ“ฆ ๋ชจ๋…ธ๋ ˆํฌ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜

๊ธฐ์กด Lerna, Yarn Workspaces ์—์„œ pnpm workspace ๋กœ ์ „ํ™˜ํ•  ๋•Œ.

Yarn Workspaces โ†’ pnpm workspace

# ๋ณ€๊ฒฝ ์ „: package.json workspaces ํ•„๋“œ
# {
#   "workspaces": ["apps/*", "packages/*"]
# }
 
# ๋ณ€๊ฒฝ ํ›„: pnpm-workspace.yaml ์‹ ๊ทœ ์ƒ์„ฑ
# pnpm-workspace.yaml
packages:
  - 'apps/*'
  - 'packages/*'
# package.json ์—์„œ workspaces ํ•„๋“œ ์ œ๊ฑฐ
# yarn.lock ์ œ๊ฑฐ
rm yarn.lock
rm -rf node_modules apps/*/node_modules packages/*/node_modules
 
# pnpm ์œผ๋กœ ์žฌ์„ค์น˜
pnpm install

workspace: ํ”„๋กœํ† ์ฝœ ๋ณ€ํ™˜

// ๋ณ€๊ฒฝ ์ „ (Yarn)
{ "@youngsu/ui": "*" }
 
// ๋ณ€๊ฒฝ ํ›„ (pnpm)
{ "@youngsu/ui": "workspace:*" }

โš ๏ธ pnpm ์˜ ์•Œ๋ ค์ง„ ์ œํ•œ์‚ฌํ•ญ

๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์ „์— ํŒ€์—๊ฒŒ ๊ณต์œ ํ•ด์•ผ ํ•  ์ œํ•œ์‚ฌํ•ญ๋“ค.

1. ํ•˜๋“œ๋งํฌ๊ฐ€ ์ง€์›๋˜์ง€ ์•Š๋Š” ํ™˜๊ฒฝ

Docker ๋นŒ๋“œ ์‹œ ์ปจํ…Œ์ด๋„ˆ-ํ˜ธ์ŠคํŠธ ๊ฐ„ ํ•˜๋“œ๋งํฌ ์ƒ์„ฑ ๋ถˆ๊ฐ€
โ†’ Docker ๋‚ด๋ถ€์—์„œ pnpm ์„ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ํ•˜๋“œ๋งํฌ ๋Œ€์‹  ๋ณต์‚ฌ(copy)
โ†’ ์„ฑ๋Šฅ ์ €ํ•˜๋Š” ์—†์œผ๋‚˜ BuildKit ์บ์‹œ๋กœ ๋ณด์™„

ํ•ด๊ฒฐ: --mount=type=cache ์‚ฌ์šฉ (06ํŽธ ์ฐธ๊ณ )

2. ์‹ฌ๋งํฌ๋ฅผ ๋”ฐ๋ผ๊ฐ€์ง€ ๋ชปํ•˜๋Š” ๊ตฌํ˜• ๋„๊ตฌ

์ผ๋ถ€ Electron ์•ฑ, ๊ตฌํ˜• webpack config, ํŠน์ • Jest transform ์ด
์‹ฌ๋งํฌ๋ฅผ ๋”ฐ๋ผ๊ฐ€์ง€ ๋ชปํ•˜๋Š” ๊ฒฝ์šฐ ๋ฐœ์ƒ

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ• (์„ ํ˜ธ๋„ ์ˆœ):
1. public-hoist-pattern ์œผ๋กœ ํ•ด๋‹น ํŒจํ‚ค์ง€ ํ˜ธ์ด์ŠคํŒ…
2. nodeLinker=hoisted (npm ๋ฐฉ์‹์œผ๋กœ ํด๋ฐฑ)
3. shamefully-hoist=true (์ตœํ›„์˜ ์ˆ˜๋‹จ)

3. ์ผ๋ถ€ ํŒจํ‚ค์ง€์˜ postinstall ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰ ์ฐจ์ด

npm ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ชจ๋“  postinstall ์„ ์‹คํ–‰ํ•˜์ง€๋งŒ
pnpm ์€ ๋ณด์•ˆ์ƒ ์ผ๋ถ€ ํŒจํ‚ค์ง€์˜ ๋นŒ๋“œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๊ธฐ๋ณธ์ ์œผ๋กœ ์Šน์ธ ํ•„์š”

ํ•ด๊ฒฐ:
pnpm approve-builds     # ํ•œ ๋ฒˆ ์‹คํ–‰ํ•˜๋ฉด ~/.pnpm-state ์— ์Šน์ธ ๋ชฉ๋ก ์ €์žฅ
๋˜๋Š”
# pnpm-workspace.yaml
onlyBuiltDependencies:
  - esbuild
  - sharp

4. Zero-Install ๋ฏธ์ง€์›

Yarn PnP ์˜ Zero-Install (node_modules ์—†์ด .yarn/cache ๋ฅผ git ์— ์ปค๋ฐ‹)
์€ pnpm ์—์„œ ์ง€์›ํ•˜์ง€ ์•Š์Œ

pnpm ์˜ ๋Œ€์•ˆ: pnpm install --offline ์œผ๋กœ ์Šคํ† ์–ด ๊ธฐ๋ฐ˜ ์˜คํ”„๋ผ์ธ ์„ค์น˜

๐Ÿ ์ด์ •๋ฆฌ

๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ 7๋‹จ๊ณ„ ์ฒดํฌ๋ฆฌ์ŠคํŠธ
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
Step 1: pnpm ์„ค์น˜ (corepack enable)
Step 2: pnpm import (lock ํŒŒ์ผ ๋ณ€ํ™˜)
Step 3: ๊ธฐ์กด node_modules / package-lock.json ์‚ญ์ œ
Step 4: .npmrc ์„ค์ • (public-hoist-pattern)
Step 5: pnpm install + dev/build/test ๊ฒ€์ฆ
Step 6: package.json ์— packageManager / engines ์ถ”๊ฐ€
Step 7: git commit (pnpm-lock.yaml ํฌํ•จ)
+์ถ”๊ฐ€: CI/CD, Docker ์—…๋ฐ์ดํŠธ (๋ณ„๋„ PR ๊ถŒ์žฅ)
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”

๐Ÿ“ ๋งˆ๋ฌด๋ฆฌ ํ€ด์ฆˆ

Q1. pnpm import ๋กœ ๋ณ€ํ™˜ํ•œ pnpm-lock.yaml ์ด ์™„์ „ํžˆ ๋™์ผํ•œ ๋ฒ„์ „์„ ๋ณด์žฅํ•˜์ง€ ์•Š๋Š” ์ด์œ ์™€, ์ด๋ฅผ ๊ฒ€์ฆํ•˜๋Š” ๋ฐฉ๋ฒ•์€?

โœ… ์ •๋‹ต: pnpm import ๋Š” ๊ธฐ์กด lock ํŒŒ์ผ์˜ ์ •๋ณด๋ฅผ ์ฐธ๊ณ ํ•˜์ง€๋งŒ, pnpm ์˜ ์˜์กด์„ฑ ํ•ด๊ฒฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ด npm/Yarn ๊ณผ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ์ผ๋ถ€ ๊ฐ„์ ‘ ์˜์กด์„ฑ์˜ ๋ฒ„์ „์ด ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ๋‹ค. ๊ฒ€์ฆ ๋ฐฉ๋ฒ•์€ ๋ณ€ํ™˜ ํ›„ ๋ฐ˜๋“œ์‹œ pnpm dev, pnpm build, pnpm test ๋ฅผ ๋ชจ๋‘ ์‹คํ–‰ํ•ด์„œ ๋™์ž‘์„ ํ™•์ธํ•˜๊ณ , ํŠนํžˆ pnpm list --depth=3 ์œผ๋กœ ํ•ต์‹ฌ ํŒจํ‚ค์ง€์˜ ๋ฒ„์ „์„ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

๐Ÿ’ก ์ƒ์„ธ ํ•ด์„ค:

  • ์ง์ ‘ ์˜์กด์„ฑ ๋ฒ„์ „์€ ๋Œ€๋ถ€๋ถ„ ์œ ์ง€๋˜์ง€๋งŒ, ๊ฐ„์ ‘ ์˜์กด์„ฑ(transitive)์€ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Œ
  • ํŠนํžˆ ํ”ผ์–ด ์˜์กด์„ฑ ํ•ด์„ ๋ฐฉ์‹์ด ๋‹ฌ๋ผ ์ผ๋ถ€ ํŒจํ‚ค์ง€๊ฐ€ ๋‹ค๋ฅธ ๋ฒ„์ „์œผ๋กœ ์„ค์น˜๋  ์ˆ˜ ์žˆ์Œ
  • ๊ฐ€์žฅ ์•ˆ์ „ํ•œ ๋ฐฉ๋ฒ•: package.json ์˜ ์ง์ ‘ ์˜์กด์„ฑ์€ ๋ฒ„์ „์„ ๋ช…ํ™•ํ•˜๊ฒŒ ๊ณ ์ •ํ•˜๊ณ  (e.g., "react": "18.2.0" exact) ๋ณ€ํ™˜ ํ›„ ๊ฒ€์ฆ
  • ๐Ÿ“Œ ํ•ต์‹ฌ ๊ธฐ์–ต๋ฒ•: "import ๋Š” ๋ฒˆ์—ญ์ด์ง€ ๋ณต์‚ฌ๊ฐ€ ์•„๋‹ˆ๋‹ค โ€” ๋ฐ˜๋“œ์‹œ ๊ฒ€์ฆ ํ…Œ์ŠคํŠธ๋ฅผ ๋Œ๋ ค๋ผ."

Q2. ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํ›„ ํŒฌํ…€ ์˜์กด์„ฑ ์—๋Ÿฌ (Cannot find module 'X') ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ, ์ด๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๋‘ ๊ฐ€์ง€ ์˜ฌ๋ฐ”๋ฅธ ์ ‘๊ทผ๋ฒ•์€?

โœ… ์ •๋‹ต: ์˜ฌ๋ฐ”๋ฅธ ๋ฐฉ๋ฒ• ์€ ๋‘ ๊ฐ€์ง€๋‹ค. ์ฒซ์งธ, ํ•ด๋‹น ํŒจํ‚ค์ง€๋ฅผ package.json ์— ๋ช…์‹œ์ ์œผ๋กœ ์ถ”๊ฐ€ (pnpm add X) ํ•˜๋Š” ๊ฒƒ์ด๋‹ค โ€” ํŒฌํ…€ ์˜์กด์„ฑ์„ ์‹ค์ œ ์˜์กด์„ฑ์œผ๋กœ ๊ฒฉ์ƒ์‹œํ‚จ๋‹ค. ๋‘˜์งธ, pnpm why X ๋กœ ์ถœ์ฒ˜๋ฅผ ํ™•์ธํ•ด์„œ ์‹ค์ œ๋กœ ํ•„์š” ์—†๋‹ค๋ฉด ํ•ด๋‹น import ๋ฌธ์„ ์ œ๊ฑฐ ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. shamefully-hoist=true ๋กœ ์—๋Ÿฌ๋ฅผ ์ˆจ๊ธฐ๋Š” ๊ฒƒ์€ ๋ฌธ์ œ๋ฅผ ๊ฐ์ถ”๋Š” ๊ฒƒ์ด์ง€ ํ•ด๊ฒฐ์ด ์•„๋‹ˆ๋‹ค.

๐Ÿ’ก ์ƒ์„ธ ํ•ด์„ค:

  • ํŒฌํ…€ ์˜์กด์„ฑ์€ "npm ์—์„  ์šด ์ข‹๊ฒŒ ๋๋˜ ์ฝ”๋“œ ํ’ˆ์งˆ ๋ฌธ์ œ" โ€” pnpm ์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ฐจ๋‹จํ•œ ๊ฒƒ
  • pnpm add X ๋กœ ์ถ”๊ฐ€ โ†’ ์ดํ›„ X ๊ฐ€ ์ง์ ‘ ์˜์กด์„ฑ์ด ๋ผ์„œ ์•ˆ์ „
  • shamefully-hoist ๋Š” ์ž„์‹œ๋ฐฉํŽธ์ด์ง€ ์ฝ”๋“œ ํ’ˆ์งˆ ํ•ด๊ฒฐ์ด ์•„๋‹˜
  • ๐Ÿ“Œ ํ•ต์‹ฌ ๊ธฐ์–ต๋ฒ•: "ํŒฌํ…€ ์—๋Ÿฌ = pnpm ์ด ์žก์•„์ค€ ์ฝ”๋“œ ๋นš โ€” ๋„๋ง์น˜์ง€ ๋ง๊ณ  pnpm add ๋กœ ๊ฐš์•„๋ผ."

Q3. ์˜์ฒ ์ด์˜ ํ…Œ์ŠคํŠธ ํƒ€์ž„: ์‹ค๋ฌด ๋”œ๋ ˆ๋งˆ (์˜์ฒ ์˜ ์„ ํƒ)

์˜์ฒ ์ด๊ฐ€ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํ›„ CI ์—์„œ๋งŒ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

Error: Cannot find module 'eslint'

๋กœ์ปฌ์—์„œ๋Š” ์ž˜ ๋˜๋Š”๋ฐ GitHub Actions ์—์„œ๋งŒ ์•ˆ ๋œ๋‹ค.
๊ฐ€๋Šฅํ•œ ์›์ธ์„ 2๊ฐ€์ง€ ์ด์ƒ ์ œ์‹œํ•˜๊ณ , ๊ฐ๊ฐ์˜ ํ™•์ธ ๋ฐฉ๋ฒ•๊ณผ ํ•ด๊ฒฐ์ฑ…์„ ์„ค๋ช…ํ•˜๋ผ.

โœ… ์ •๋‹ต: ์›์ธ 1: ๋กœ์ปฌ ~/.npmrc ์— public-hoist-pattern[]=*eslint* ๊ฐ€ ์žˆ์ง€๋งŒ ํ”„๋กœ์ ํŠธ .npmrc ์—๋Š” ์—†๋Š” ๊ฒฝ์šฐ. ์›์ธ 2: CI workflow ์—์„œ pnpm/action-setup ์ด ์—†๊ฑฐ๋‚˜ cache: 'pnpm' ์ด ๋ˆ„๋ฝ๋˜์–ด ์บ์‹œ ์—†์ด ์ƒˆ๋กœ ์„ค์น˜ํ•˜๋ฉด์„œ ๋™์ž‘์ด ๋‹ฌ๋ผ์ง€๋Š” ๊ฒฝ์šฐ. ์›์ธ 3: workflow ์— ์—ฌ์ „ํžˆ npm ci ๊ฐ€ ๋‚จ์•„์žˆ๋Š” ๊ฒฝ์šฐ.

๐Ÿ’ก ์ƒ์„ธ ํ•ด์„ค:

  • ์›์ธ 1 ํ™•์ธ: cat .npmrc vs cat ~/.npmrc ๋น„๊ต / ํ•ด๊ฒฐ: ํ”„๋กœ์ ํŠธ .npmrc ์— ํŒจํ„ด ์ถ”๊ฐ€ ํ›„ ์ปค๋ฐ‹
  • ์›์ธ 2 ํ™•์ธ: workflow ์— pnpm/action-setup@v4 ์Šคํ…์ด ์žˆ๋Š”์ง€ ํ™•์ธ / ํ•ด๊ฒฐ: setup ์Šคํ… ์ถ”๊ฐ€
  • ์›์ธ 3 ํ™•์ธ: workflow ์— npm ci ๊ฐ€ ์žˆ๋Š”์ง€ grep / ํ•ด๊ฒฐ: pnpm install --frozen-lockfile ์œผ๋กœ ๊ต์ฒด
  • ํ•ต์‹ฌ ์›์น™: "๋กœ์ปฌ OK, CI ์‹คํŒจ = ํ™˜๊ฒฝ ์„ค์ •์ด ๋‹ค๋ฅธ ๊ฒƒ์ด๋‹ค โ€” ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ ํŒŒ์ผ๋กœ ํ†ต์ผํ•˜๋ผ."
  • ๐Ÿ“Œ ํ•ต์‹ฌ ๊ธฐ์–ต๋ฒ•: "์„ค์ •์€ ํ™ˆ ๋””๋ ‰ํ† ๋ฆฌ๊ฐ€ ์•„๋‹Œ ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ .npmrc ์— โ€” ๊ทธ๋ž˜์•ผ CI ๋„ ๊ฐ™๋‹ค."

๐Ÿฃ ์˜์ฒ ์ด์˜ ํ‡ด๊ทผ ์ผ๊ธฐ

๋“œ๋””์–ด pnpm ๊ฐ€์ด๋“œ 7ํŽธ ๋งˆ์ง€๋ง‰์ด๋‹ค.

์†”์งํžˆ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์ฑ•ํ„ฐ๊ฐ€ ์ฒ˜์Œ์—” ๋ณ„๊ฑฐ ์—†์„ ๊ฒƒ ๊ฐ™์•˜๋Š”๋ฐ, ๋ง‰์ƒ ์ •๋ฆฌํ•˜๋‹ค ๋ณด๋‹ˆ ํ•จ์ •์ด ์ƒ๊ฐ๋ณด๋‹ค ๋งŽ์•˜๋‹ค. ํŒฌํ…€ ์˜์กด์„ฑ ์—๋Ÿฌ, ๋กœ์ปฌ-CI ํ™˜๊ฒฝ ์ฐจ์ด, Husky hooks ์žฌ์„ค์ •, Prisma postinstall... ํ•˜๋‚˜ํ•˜๋‚˜๋Š” ๋ณ„๊ฒŒ ์•„๋‹ˆ์ง€๋งŒ ๋™์‹œ์— ์—ฌ๋Ÿฌ ๊ฐœ๊ฐ€ ํ„ฐ์ง€๋ฉด ์ •๋ง ํŒจ๋‹‰์ด ์˜ฌ ์ˆ˜ ์žˆ๊ฒ ๋‹ค ์‹ถ์—ˆ๋‹ค.

์˜ํ˜ธ ๋ฆฌ๋“œ ๋‹˜์ด "๊ธ‰ํ•˜๊ฒŒ ํ•˜๋ฉด ๊ผญ ๋ญ”๊ฐ€ ๋น ์ง„๋‹ค"๊ณ  ํ•˜์‹  ๋ง์”€์ด ์ด์ œ์„œ์•ผ ์ง„์งœ๋กœ ์ดํ•ด๋๋‹ค. ์ฒดํฌ๋ฆฌ์ŠคํŠธ ํ•˜๋‚˜์”ฉ ๋ฐŸ์•„๊ฐ€๋Š” ๊ฒŒ ๊ฒฐ๊ตญ ๊ฐ€์žฅ ๋น ๋ฅธ ๊ธธ์ด๋‹ค. ๊ธ‰ํ•˜๊ฒŒ ๋‹ฌ๋ฆฌ๋‹ค๊ฐ€ ๋น ์ง„ ๊ฑฐ ์ฐพ์œผ๋Ÿฌ ๋˜๋Œ์•„๊ฐ€๋Š” ๊ฒƒ๋ณด๋‹ค.

pnpm ๊ฐ€์ด๋“œ 7ํŽธ์„ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋๊นŒ์ง€ ๋‹ค ์ผ๋‹ค. ๋ฉ˜ํƒˆ ๋ชจ๋ธ, node_modules ๊ตฌ์กฐ, CLI, workspace, Catalogs, CI/Docker, ๊ทธ๋ฆฌ๊ณ  ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜๊นŒ์ง€. ์ฒ˜์Œ pnpm ์„ ์•Œ์•˜์„ ๋•Œ "๊ทธ๋ƒฅ npm ์ด๋ž‘ ๋น„์Šทํ•œ ๊ฑฐ ์•„๋ƒ?" ๋ผ๊ณ  ์ƒ๊ฐํ–ˆ๋Š”๋ฐ, ์ด์ œ pnpm ์ด ์–ผ๋งˆ๋‚˜ ๋‹ค๋ฅด๊ณ  ์–ผ๋งˆ๋‚˜ ์ž˜ ์„ค๊ณ„๋œ ๋„๊ตฌ์ธ์ง€ ์ œ๋Œ€๋กœ ์•Œ๊ฒŒ ๋๋‹ค.

๐Ÿ’ก ์˜ค๋Š˜์˜ ๊ตํ›ˆ: "๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์€ ๊ฒฐ์Šน์„ ์ด ์•„๋‹ˆ๋ผ ์ถœ๋ฐœ์„ ์ด๋‹ค. ์ˆœ์„œ๋ฅผ ์ง€ํ‚ค๊ณ , ๊ฒ€์ฆํ•˜๊ณ , ํŒ€์—๊ฒŒ ๊ณต์œ ํ•˜๋ฉด โ€” ๊ทธ๋•Œ๋ถ€ํ„ฐ pnpm ์˜ ์ง„์งœ ์ด์ ์„ ๋ˆ„๋ฆด ์ˆ˜ ์žˆ๋‹ค."

๋‚ด์ผ๋ถ€ํ„ฐ๋Š” ์‹ค์ œ ํ”„๋กœ์ ํŠธ์— pnpm ์„ ์ ์šฉํ•ด๋ณผ ์ฐจ๋ก€๋‹ค. ์ด๋ก ์€ ์ถฉ๋ถ„ํžˆ ์Œ“์•˜๋‹ค. ์ด์ œ ์‹ค์ „์ด๋‹ค. ์˜ํ˜ธ ๋ฆฌ๋“œ ๋‹˜์ด ์ž˜ ํ–ˆ๋‹ค๊ณ  ์Šคํ‹ฐ์ปค ํ•˜๋‚˜ ์ฃผ์…จ๋‹ค. ์˜ค๋Š˜์€ ๊ธฐ๋ถ„ ์ข‹๊ฒŒ ์ง‘ ๊ฐ€์„œ ๋ง›์žˆ๋Š” ๊ฑฐ ๋จน์–ด์•ผ์ง€.


๐Ÿ”— ๋” ์•Œ์•„๋ณด๊ธฐ