motthay

tại sao tôi chọn pnpm cho monorepo

#002

Hồi đầu năm tôi migrate astr0 từ npm sang pnpm. Quyết định này không đến từ việc “pnpm nhanh hơn npm” (dù đúng là nó nhanh hơn thật). Nó đến từ một vấn đề cụ thể: workspace management.

Vấn đề với npm workspaces

npm workspaces hoạt động, nhưng có 3 điểm đau:

  1. Hoisting không đoán trước được — Bạn không biết chắc package nào sẽ được hoist lên root node_modules. Điều này dẫn đến tình trạng “nó chạy trên máy tôi nhưng không chạy trên CI.”

  2. Không có catalog — Khi 6 site dùng chung version Astro, mỗi lần update là phải sửa từng package.json. Với pnpm catalog, tôi đổi một chỗ trong pnpm-workspace.yaml, tất cả site tự động theo.

  3. Disk usage — Với npm, mỗi workspace clone dependencies riêng. Với pnpm content-addressable store, 6 site dùng chung một bản copy của mỗi package. Tiết kiệm ~60% disk.

Cái tôi thực sự thích

Không phải tốc độ. Là strictness.

pnpm không cho phép package A import package B trừ khi A đã declare B là dependency. Nghe có vẻ hiển nhiên, nhưng npm/yarn cho phép việc này — và nó tạo ra “phantom dependencies”: code của bạn chạy hôm nay, nhưng ngày mai ai đó xóa B khỏi node_modules của một package khác, và mọi thứ vỡ.

pnpm bắt bạn phải rõ ràng về dependencies. Điều này làm tôi tự tin hơn khi push lên production.

Lời khuyên nếu bạn muốn chuyển

  • Đọc pnpm workspaces doc trước
  • Bắt đầu với pnpm import để generate lockfile từ file cũ
  • Dùng pnpm-workspace.yaml catalog để lock version chung
  • CI nên dùng pnpm install --frozen-lockfile

Tóm lại: pnpm không phải là công cụ “ngầu nhất.” Nhưng với monorepo, nó là công cụ đúng đắn nhất tôi từng dùng.