pnpm 常用命令有哪些?与 npm 命令有什么区别?
核心回答
pnpm 常用命令与 npm 高度相似,关键差异在于:npm install <pkg> 对应 pnpm add <pkg>;npx 对应 pnpm dlx;monorepo 用 pnpm -r(递归)和 pnpm --filter(按包过滤)替代 npm workspaces。但命令相似只是表象,真正的区别在于底层机制——pnpm 使用内容寻址存储(content-addressable store)+ 符号链接结构,解决了 npm 的幽灵依赖和磁盘浪费问题。
追问:为什么 pnpm 不存在幽灵依赖?
npm 采用扁平化 node_modules,所有依赖都被提升到顶层,导致代码能 import 未声明的包。pnpm 通过 .pnpm 目录存放硬链接,再用 symlink 严格映射到项目 node_modules,只暴露 package.json 中声明的依赖。
追问:pnpm add 和 npm install 的区别?
npm install <pkg> 既用于安装所有依赖(无参数),也用于添加单个包。pnpm 将这两个职责拆分:pnpm install 安装已有依赖,pnpm add 添加新包,语义更清晰。
安装与依赖管理
bash# 安装所有依赖 pnpm install # 添加依赖(默认 dependencies) pnpm add lodash pnpm add lodash@4.17.21 # 添加到不同依赖组 pnpm add lodash -D # devDependencies pnpm add lodash -O # optionalDependencies pnpm add lodash --save-peer # peerDependencies # 全局安装 pnpm add -g typescript
更新与删除
bash# 更新 pnpm update lodash # 更新单个包 pnpm up -L # 更新所有包到最新版 pnpm up -i # 交互式选择更新 # 删除 pnpm remove lodash pnpm rm lodash express # 删除多个包 pnpm remove -g lodash # 删除全局包
运行脚本与执行包
bash# 运行 package.json 中的脚本 pnpm build # 等同 pnpm run build pnpm test # 传递参数 pnpm build -- --watch # 执行远程包(替代 npx) pnpm dlx create-vite my-app
追问:pnpm dlx 和 npx 有什么区别?
pnpm dlx 下载包到临时目录执行,不污染全局。npx 在 npm 5.2+ 中引入,行为类似但会优先查找本地已安装的包。两者核心场景一致,但 pnpm dlx 的临时隔离更彻底。
Monorepo 命令
pnpm 原生支持 monorepo,通过 pnpm-workspace.yaml 声明工作区,配合 --filter 实现精准的包范围操作:
bash# 在指定包中执行 pnpm --filter @scope/pkg build pnpm -F @scope/pkg build # 递归执行(所有包) pnpm -r build # 并行执行 pnpm -r --parallel build # 只执行有变更的包 pnpm -r --filter "...[origin/main]" build
追问:pnpm workspace 和 npm workspaces 的核心差异?
pnpm workspace 默认严格隔离依赖,通过 .npmrc 的 shamefully-hoist=true 可切换为扁平模式;npm workspaces 默认扁平提升。pnpm 的 --filter 支持正则、依赖图范围等灵活选择,npm 的 --workspace 功能相对简单。实际项目中 pnpm workspace 的依赖隔离更可靠,避免子包间隐式依赖。
Store 管理
pnpm 的核心优势来自全局 store,所有项目共享同一份包存储:
bashpnpm store path # 查看 store 路径 pnpm store prune # 清理未引用的包,释放磁盘 pnpm store verify # 验证 store 完整性
追问:pnpm store 的硬链接机制如何节省磁盘?
所有项目共享一个全局 store(默认 ~/.local/share/pnpm/store),每个包只存一份。项目 node_modules 中通过硬链接指向 store,不复制文件。10 个项目用同一个版本的 lodash,磁盘只占一份空间。这也是 pnpm 安装速度比 npm 快 2-3 倍的原因——大部分包已在 store 中,只需创建链接。
命令速查对比
| 功能 | npm | pnpm | 差异说明 |
|---|---|---|---|
| 安装依赖 | npm install | pnpm install | 语义一致 |
| 添加包 | npm install <pkg> | pnpm add <pkg> | pnpm 语义更清晰 |
| 删除包 | npm uninstall <pkg> | pnpm remove <pkg> | 命令名不同 |
| 运行脚本 | npm run <cmd> | pnpm <cmd> | pnpm 可省略 run |
| 执行远程包 | npx <cmd> | pnpm dlx <cmd> | dlx 隔离更彻底 |
| 查看依赖 | npm list | pnpm list | 语义一致 |
| 查看过时包 | npm outdated | pnpm outdated | 语义一致 |
| 安全审计 | npm audit | pnpm audit | 语义一致 |
| 全局安装 | npm install -g | pnpm add -g | add vs install |
| Monorepo | --workspace | --filter | filter 更灵活 |
其他实用命令
bashpnpm init # 初始化 package.json pnpm create vite # 用模板创建项目 pnpm import # 从 npm/yarn 锁文件迁移 pnpm link ../local-pkg # 链接本地包 pnpm why lodash # 查看包被谁依赖 pnpm config list # 查看配置 pnpm config set registry https://registry.npmmirror.com # 设置镜像源 pnpm outdated # 检查过时依赖 pnpm audit # 安全审计