Command Line cho Developer · Part 8 - Node, npm, pnpm & Package Scripts
Workflow Node/package manager trong terminal: node/npm/pnpm version, corepack, npm run, pnpm exec/dlx, npm ci, frozen lockfile, env vars, npm ls và pnpm why.
Đây là Phần 8. Với frontend/fullstack JavaScript, rất nhiều việc hằng ngày đi qua package manager:
- cài dependencies;
- chạy dev server;
- chạy build/test/lint;
- gọi CLI local của project;
- debug dependency bị lệch version.
Bài này tập trung vào workflow terminal, không đào sâu toàn bộ package manager. Muốn học sâu hơn, xem series Node Package Managers & the Supply Chain.
Kiểm tra version
node --version
npm --version
pnpm --version
Xem Node đang ở đâu:
command -v node
node -p "process.execPath"
node -p "process.version"
Nếu team dùng version manager như nvm, fnm, asdf, hãy kiểm tra file:
ls -la | rg '.nvmrc|.node-version|package.json'
Node version lệch là nguồn lỗi rất thường gặp, nhất là khi native dependency hoặc framework mới yêu cầu version cụ thể.
Corepack và package manager
Corepack giúp pin package manager theo packageManager trong package.json.
corepack enable
corepack prepare pnpm@latest --activate
Xem project yêu cầu gì:
node -p "require('./package.json').packageManager"
Nếu repo có pnpm-lock.yaml, thường dùng pnpm. Nếu có package-lock.json, thường dùng npm. Đừng trộn package manager nếu team không chủ động làm vậy.
Đọc scripts trong package.json
npm run
pnpm run
Chạy script:
npm run dev
npm run build
npm run test
Với pnpm:
pnpm dev
pnpm build
pnpm test
Nhưng dạng rõ nhất vẫn là:
pnpm run build
Trong repo lạ, đọc script trước:
node -p "require('./package.json').scripts"
Hoặc đẹp hơn nếu có jq:
jq '.scripts' package.json
Gọi CLI local: npm exec, pnpm exec, dlx
Dependency CLI cài trong project nằm ở node_modules/.bin.
Chạy CLI local:
npm exec astro -- --version
pnpm exec astro --version
Với pnpm, pnpm exec rất thường dùng:
pnpm exec tsc --noEmit
pnpm exec prettier --check .
Chạy package tạm thời không cài vào project:
npm exec cowsay hello
pnpm dlx cowsay hello
dlx hợp cho tool một lần. Với tool team cần lặp lại, nên đưa vào devDependencies và scripts để mọi người chạy cùng version.
Cài dependency
Npm:
npm install react
npm install -D vitest
Pnpm:
pnpm add react
pnpm add -D vitest
Cài đúng theo lockfile trong CI:
npm ci
pnpm install --frozen-lockfile
Khác biệt quan trọng:
| Lệnh | Dùng khi |
|---|---|
npm install | dev local, có thể update lockfile |
npm ci | CI, cài sạch theo lockfile |
pnpm install | dev local |
pnpm install --frozen-lockfile | CI, không cho lockfile đổi |
Debug dependency
Npm:
npm ls react
npm explain react
Pnpm:
pnpm why react
pnpm list react
Xem version package trực tiếp:
node -p "require('astro/package.json').version"
Nếu import fail:
node -e "console.log(require.resolve('astro/package.json'))"
Với ESM-only package, require có thể không load module chính, nhưng package.json thường vẫn resolve được.
Env khi chạy script
NODE_ENV=production npm run build
DEBUG=1 pnpm test
PORT=4322 pnpm run dev
Trên Windows cmd, cú pháp env inline khác. Nếu team cần cross-platform scripts, dùng tool như cross-env hoặc để config trong file/framework.
Xem env trong script:
node -e "console.log(process.env.NODE_ENV)"
Đừng commit .env chứa secret. Commit .env.example để người khác biết cần biến nào.
Dọn cài đặt khi dependency rối
Trước tiên đọc lỗi. Nếu thật sự cần reset:
rm -rf node_modules
npm ci
Với pnpm:
rm -rf node_modules
pnpm install --frozen-lockfile
Nếu lockfile bị đổi ngoài ý muốn, xem diff:
git diff -- package-lock.json pnpm-lock.yaml
Không xóa lockfile chỉ để “cho nó chạy” nếu bạn không hiểu hậu quả. Lockfile là một phần của source truth.
Recipe trong repo lạ
node --version
npm --version
pnpm --version
ls -la
jq '.packageManager, .scripts' package.json
git status --short
Nếu là pnpm:
pnpm install --frozen-lockfile
pnpm run build
pnpm run check
Nếu là npm:
npm ci
npm run build
npm run check
Bài tập
- In scripts của project bằng
npm runhoặcpnpm run. - Dùng
jqhoặcnode -pđọcpackageManager. - Chạy một CLI local bằng
pnpm exechoặcnpm exec. - Dùng
npm lshoặcpnpm whykiểm tra một dependency.
Lời giải tham khảo
pnpm run
node -p "require('./package.json').packageManager"
pnpm exec astro --version
pnpm why astroĐiều cốt lõi
Package manager không chỉ để cài package. Nó là entrypoint của workflow project: scripts, CLI local, dependency graph, CI reproducibility. Đọc package.json, tôn trọng lockfile, và chạy tool qua package manager để đúng version của repo.