pnpm update/up无法升级包原因?

问题

## 基于up/update 无法升级包版本
mac@GaGa oss-bucket-policy % pnpm update -g @openai/codex
Already up to date
Progress: resolved 27, reused 8, downloaded 0, added 0, done
Done in 564ms using pnpm v10.33.0
mac@GaGa oss-bucket-policy % pnpm up -g @openai/codex
Already up to date
Progress: resolved 27, reused 8, downloaded 0, added 0, done
Done in 487ms using pnpm v10.33.0

## add是正常的
mac@GaGa oss-bucket-policy % pnpm add  -g @openai/codex
Packages: +2 -2
++--
Downloading @openai/codex@0.121.0-darwin-arm64: 72.84 MB/72.84 MB, done
Progress: resolved 27, reused 6, downloaded 2, added 2, done

/Users/mac/Library/pnpm/global/5:
- @openai/codex 0.120.0
+ @openai/codex 0.121.0

Done in 5s using pnpm v10.33.0

奇怪:为什么pnpm up/update 无法升级包,add却可以?


mac@GaGa ~ % pnpm -h
Version 10.33.0
Usage: pnpm [command] [flags]
       pnpm [ -h | --help | -v | --version ]

These are common pnpm commands used in various situations, use 'pnpm help -a' to list all commands

Manage your dependencies:
      add                  Installs a package and any packages that it depends on. By default, any new package is installed as a prod dependency  ## 默认安装最新版本
   i, install              Install all dependencies for a project
  ln, link                 Connect the local project to another one
  rm, remove               Removes packages from node_modules and from the project's package.json
      unlink               Unlinks a package. Like yarn unlink but pnpm re-installs the dependency after removing the external link
  up, update               Updates packages to their latest version based on the specified range  ## 更新在依赖版本范围内
...

1.问题本质

你这个现象不是异常,而是 pnpm 设计行为 + 版本解析机制共同作用的结果

  • pnpm up / update只在当前 semver 范围内升级
  • pnpm add -g重新解析版本范围(默认拉最新)

核心区别在于:

命令 行为本质 是否突破版本范围
pnpm up 根据已有版本约束更新 ❌ 不会
pnpm update up(别名) ❌ 不会
pnpm add -g 重新安装并解析版本 ✅ 会

2.为什么 pnpm up 显示 Already up to date

1.全局包的版本约束来源

pnpm 全局安装实际上也是一个“虚拟项目”,路径:

1
~/Library/pnpm/global/5/package.json

这里会有类似:

1
2
3
4
5
{
"dependencies": {
"@openai/codex": "^0.120.0"
}
}

2.semver 行为关键点

你当前版本:

0.120.0

新版本:

0.121.0

但是注意:

⚠️ 0.x 版本是特殊规则(破坏性版本)

semver 规则:

当前依赖 允许升级范围
^0.120.0 >=0.120.0 <0.121.0

👉 结论:

0.121.0 不在 ^0.120.0 范围内

所以:

1
pnpm up -g @openai/codex

判定:已经是该范围内最新版本 → 不升级


3.为什么 pnpm add -g 能升级

执行:

1
pnpm add -g @openai/codex

行为是:

  1. 重新解析 registry 最新版本
  2. 更新 package.json 中的版本范围
  3. 直接安装最新版本

等价于:

1
pnpm add -g @openai/codex@latest

所以:

0.120.0 → 0.121.0

4.包版本升级

1.强制升级(推荐)

1
pnpm add -g @openai/codex@latest

1
pnpm up -g @openai/codex --latest

2.批量升级所有全局包

1
pnpm up -g --latest

3.不要依赖默认semver 行为

对于 CLI 工具(如 codex):

  • 推荐策略:
1
pnpm add -g @openai/codex@latest

或 CI 中:

1
pnpm up -g --latest

5.底层机制总结

行为流程对比

flowchart TD
    A[pnpm up] --> B[读取package.json]
    B --> C[解析版本范围 ^0.120.0]
    C --> D[查找范围内最新版本]
    D --> E[仍是0.120.0]
    E --> F[Already up to date]

    A2[pnpm add -g] --> B2[查询registry最新版本]
    B2 --> C2[获取0.121.0]
    C2 --> D2[更新依赖范围]
    D2 --> E2[安装新版本]

6.总结

pnpm up 是“范围内升级”(小版本内升级),pnpm add 是“重新定义范围 + 安装最新”,而 0.x 版本的 semver 会严格限制升级区间。