pnpm 常用命令速查(add、update)
pnpm
更新 pnpm
pnpm add -g pnpm
add
| 命令 | 用法 |
|---|---|
| pnpm add sax | 保存到 dependencies |
| pnpm add -D sax | 保存到 devDependencies |
update
| 命令 | 用法 |
|---|---|
| pnpm up | 遵循 package.json 指定的范围更新所有的依赖项 |
| pnpm up --latest | 更新所有依赖项,此操作会忽略 package.json 指定的范围 |
| pnpm up foo@2 | 将 foo 更新到 v2 上的最新版本 |
| pnpm up "@babel/*" | 更新 @babel 范围内的所有依赖项 |
up 是 update 的别名,两个写法完全等价。这里最容易搞混的是「遵循范围」和 --latest 的区别:package.json 里写 "vue": "^3.2.0",pnpm up 最多把它升到 3.x 的最新版,并且不会改动 package.json 里的这行文本,只更新 pnpm-lock.yaml;而 pnpm up --latest 会直接跳到 4.x(如果有),同时把 package.json 里的范围重写成 ^4.x.x。所以 --latest 是会产生 package.json diff 的破坏性操作,跑之前最好先 commit 一次。
另外 pnpm up "@babel/*" 里的引号不能省。不加引号的话 * 会先被 shell 展开成当前目录下的文件名,命令就变成了一串莫名其妙的参数。
交互式更新更好用
命令行里逐个指定版本很麻烦,我平时更常用交互模式:
# 打开一个可勾选的列表,空格选中,回车确认
pnpm up -i
# 交互式 + 忽略 package.json 范围(跨大版本升级用这个)
pnpm up -i --latest
# monorepo 里对所有子包一起做交互式更新
pnpm up -i -r
它会把依赖按 dependencies / devDependencies 分组列出来,标出当前版本和目标版本,还会给出 changelog 链接。跨大版本升级时挨个确认比一把梭 --latest 安全得多。
remove 与 dlx
| 命令 | 用法 |
|---|---|
pnpm rm sax | 卸载依赖,等价于 pnpm remove / pnpm uninstall |
pnpm rm -g sax | 卸载全局依赖 |
pnpm dlx create-vite | 临时下载并执行包,不写入项目依赖(对应 npx) |
pnpm exec vite build | 执行已安装在 node_modules/.bin 里的命令 |
dlx 和 exec 的分工要记清:dlx 是「本地没有,临时拉一份跑完就扔」,exec 是「本地已经装了,直接跑」。用 dlx 去跑项目里已装的工具会白下载一遍,用 exec 去跑没装的包则直接报找不到命令。
安装相关的常用参数
# 严格按 lock 文件安装,lock 与 package.json 不一致时直接报错退出
# CI 里应该固定用这个,避免构建时悄悄改动 lock
pnpm install --frozen-lockfile
# 只装 dependencies,跳过 devDependencies(构建产物镜像里用)
pnpm install --prod
# 递归对工作区所有包执行脚本
pnpm -r build
# 只对指定包及其依赖执行
pnpm --filter @app/web build
--frozen-lockfile 在 CI 环境下其实是默认开启的(pnpm 检测到 CI 环境变量就会自动启用),但本地跑验证时得手动加。我遇到过本地 pnpm install 一切正常、CI 直接失败的情况,原因就是有人改了 package.json 的版本范围却忘了提交更新后的 pnpm-lock.yaml。
查看真实的包位置
pnpm 的 node_modules 是符号链接指向全局 store 的,排查「装的到底是哪个版本」时这两条命令很有用:
# 查看某个包被哪些依赖引入、有几个版本共存
pnpm why vue
# 查看全局 store 路径
pnpm store path
# 清理 store 中已无人引用的包
pnpm store prune
pnpm why 是排查版本冲突的主力工具。同一个库在依赖树里出现多个版本时,它能直接告出每个版本是被谁拉进来的,比手工翻 lock 文件快很多。

还没有留言,来发表第一条吧~