· pnpm / nodejs / package-manager
pnpm 10 đánh giá — có gì mới và có đáng nâng cấp không?
pnpm 10 chặn lifecycle scripts của dependency theo mặc định — đây là thay đổi breaking duy nhất. Những gì thực sự thay đổi, ai nên nâng cấp và ai nên chờ.
Bởi Ethan · Cập nhật 31 tháng 5, 2026
1.084 từ · 6 phút đọc
Nếu bạn đang bắt đầu dự án mới hoặc muốn isolation nghiêm ngặt hơn cho dependency, hãy nâng cấp pnpm 10 ngay. Nếu quá trình cài đặt của bạn phụ thuộc vào postinstall scripts của các package bên thứ ba, hoặc bạn chạy linter từ monorepo root, hãy dành nửa ngày để audit và thêm allowlist trước khi bump version.
Bài này dành cho ai
Developer Node.js đang quản lý dependency bằng pnpm — cá nhân, team, hay monorepo — và đang cân nhắc xem v10 có xứng đáng với công sức migration không. Nếu bạn đang dùng pnpm 8 trở xuống, hãy đọc changelog của v9 trước. Nếu đang cân nhắc giữa các package manager, xem thêm pnpm vs npm hoặc pnpm vs Yarn.
Những gì thay đổi trong pnpm 10
Lifecycle scripts bị chặn theo mặc định
Đây là thay đổi duy nhất sẽ phá vỡ hầu hết dự án ngay lần install đầu tiên.
pnpm 10 không còn thực thi lifecycle scripts (postinstall, prepare, preinstall) cho bất kỳ dependency nào trừ khi bạn chủ động cho phép. Release notes viết thẳng:
“Lifecycle scripts of dependencies are not executed during installation by default! This is a breaking change aimed at increasing security.”
Động cơ đằng sau thay đổi này rất thực tế. postinstall là vector tấn công phổ biến nhất trong các cuộc tấn công supply chain: một package bị compromise có thể chạy code tùy ý trên máy của mọi developer và mọi CI runner khi cài đặt. pnpm 10 đóng khe hở đó theo mặc định.
Để bật lại scripts cho các package thực sự cần — native modules, bất cứ thứ gì cần compile C++ hoặc tải binary về lúc install — thêm allowlist vào package.json:
{
"pnpm": {
"onlyBuiltDependencies": ["esbuild", "sharp", "@img/sharp-darwin-arm64"]
}
}
Nếu bạn không chắc package nào cần postinstall, chạy pnpm approve-builds (có từ v10.1.0):
pnpm approve-builds
CLI tương tác sẽ liệt kê từng package có build script và cho bạn phê duyệt hoặc từ chối từng cái. Từ v10.32, pnpm approve-builds --all phê duyệt tất cả trong một lần — tiện trong giai đoạn migration khi bạn muốn khôi phục hành vi cũ tạm thời để tiến hành audit sau.
public-hoist-pattern giờ rỗng
Ở pnpm 9 và trước đó, các package eslint và prettier được tự động hoist lên node_modules/.bin tại workspace root. Tính năng đó đã bị bỏ.
“Nothing is hoisted by default. Packages containing
eslintorprettierin their name are no longer hoisted.”
Các monorepo chạy eslint từ root qua script như "lint": "eslint ." sẽ thấy lỗi Cannot find module 'eslint' hoặc eslint: command not found. Cách sửa: cài eslint trực tiếp ở root, hoặc cấu hình public-hoist-pattern trong .npmrc:
public-hoist-pattern[]=*eslint*
public-hoist-pattern[]=*prettier*
Store version tăng lên v10
Content-addressable store chuyển sang dùng SHA256 xuyên suốt và có cấu trúc thư mục index/ mới. Lần install đầu tiên sau khi nâng cấp pnpm, một số package có thể tải lại khi pnpm điều chỉnh format store cũ sang mới. Đây là chi phí một lần duy nhất. Store cũ tại ~/.pnpm-store/v3 (v9) không bị xóa tự động — chạy pnpm store prune khi bạn chắc chắn việc nâng cấp đã ổn định.
Hiệu năng
Trang benchmark của pnpm.io (kiểm tra ngày 31/05/2026) ghi nhận install JS-baseline với cache + lockfile + node_modules đạt khoảng 449ms. Phiên bản Rust engine của pnpm (pnpm 🦀) xử lý cùng kịch bản đó trong 56ms — nhanh hơn khoảng 8 lần.
Một lưu ý: tài liệu chính thức không công bố so sánh JS-baseline side-by-side giữa v9 và v10. Con số 449ms phản ánh throughput của v10 hiện tại, không phải mức chênh lệch so với v9.
Hướng dẫn nâng cấp
-
Cập nhật
packageManagertrongpackage.json:{ "packageManager": "[email protected]" } -
Chạy
pnpm installvà đọc kỹ output. pnpm sẽ liệt kê các package có lifecycle scripts bị chặn. -
Chạy
pnpm approve-buildsđể quyết định tương tác package nào cần build scripts. Các lựa chọn được ghi vàopnpm.onlyBuiltDependenciestrongpackage.json. -
Sửa hoisting nếu workspace của bạn chạy linter từ root. Thêm chúng vào
public-hoist-patterntrong.npmrc, hoặc cài tooling trực tiếp tại workspace root. Để bootstrap monorepo pnpm + Turborepo đúng cách, xem Cách thiết lập monorepo pnpm + Turborepo từ đầu. -
Cập nhật CI. Nếu pipeline đang set
PNPM_HOMEhoặc dùng pnpm setup action, bump version ở đó luôn. Ví dụ với GitHub Actions:- uses: pnpm/action-setup@v4 with: version: 10 -
Kiểm tra issue #9082 nếu bạn đang chạy
shared-workspace-lockfile=false. Tại thời điểm viết bài,onlyBuiltDependencieskhông hoạt động đúng với cấu hình đó. Giải pháp tạm thời là bật lại scripts toàn cục vớienable-pre-post-scripts=truetrong.npmrccho các package bị ảnh hưởng, rồi theo dõi issue upstream để chờ bản sửa chính thức.
Không có trang migration chính thức tại pnpm.io/migration/v10 — nguồn tham khảo thực tế là release notes v10.0.0 trên GitHub. Cũng không có codemod tự động (có codemod cho v10→v11, nhưng không có cho v9→v10).
Kết luận
Nâng cấp ngay nếu:
- Bạn đang bắt đầu dự án mới.
- Bạn muốn bảo vệ nghiêm ngặt hơn khỏi supply-chain attacks — việc chặn lifecycle scripts là cải thiện bảo mật có thực chất.
- Bạn đã quản lý danh sách
onlyBuiltDependenciestường minh từ trước.
Chờ thêm nếu:
- Pipeline cài đặt của bạn phụ thuộc vào nhiều
postinstallscripts của bên thứ ba chưa được audit. - Bạn đang chạy linter từ monorepo root và chưa có thời gian giải quyết vấn đề hoisting.
- Bạn dùng
shared-workspace-lockfile=falsevới cấu hình workspace phức tạp, chờ issue #9082 được đóng.
Những điều cần lưu ý
- Chúng tôi không kiểm tra trên Windows. pnpm vốn có vài vấn đề lẻ tẻ trên Windows liên quan đến symlink — hãy tự xác minh trên môi trường đó.
- Không có số liệu so sánh JS-baseline giữa v9 và v10 từ team pnpm tại thời điểm đăng bài. Con số 449ms là throughput của v10, không phải mức cải thiện đo được so với v9.
- Affiliate links: không có. pnpm là open-source.