DEBUG.WIKI
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →
OnlineSIM:在线接收短信,虚拟号码租用
RackNerd;$21.99/年 · 1GB KVM

pnpm 10 切到 12 后生成的锁文件,下一次 frozen 安装失败

自动切换显示 pnpm 12,锁文件却没有包管理器依赖文档。检查启动链继承的 pm_on_fail=ignore,直接使用目标版本重新生成可审查差异。

锁文件维护任务显示已用 pnpm 12.15.0 完成,CI 随后却报 Cannot update packageManagerDependencies with "frozen-lockfile" because the lockfile is not up to date。若维护任务最初由 pnpm 10 启动,检查自动版本切换传下来的环境变量。

明确复现组合是 PATH 上的 pnpm 10.34.7 或 10.34.8,package.json 固定 "packageManager": "pnpm@12.15.0",并且从不存在锁文件的状态生成。旧锁文件本来已经有包管理器文档时,切换不一定把它删除,因此只测增量更新可能看不出问题。

显示目标版本,不代表启动环境相同

pnpm 10 的切换子进程除了关闭二次版本管理,还传入 pnpm_config_pm_on_fail=ignore。目标 pnpm 12.15.0 在这条 ignore 分支提前返回,没有同步包管理器 pin 的锁文件记录。

这能解释两种结果:直接调用相同的 12.15.0 可以写出相应文档,经旧版自动切换则没有。不要只凭终端最后一行“using pnpm v12.15.0”判断两次任务完全相同。

这里缺的是 pnpm 自身的 packageManagerDependencies 环境记录,不是应用依赖的 importers 都丢失。已有双 YAML 文档的读取选择问题属于消费工具解析,应另外处理。

用明确的目标可执行程序重新生成

保存错误锁文件、清单与维护任务日志,在隔离工作区直接调用经过核对的 pnpm 12.15.0。不要让同一条命令再由 pnpm 10 自动切换;也要检查 CI 是否显式继承了上述 ignore 环境变量。

例如,假设团队已经安装并核验 /opt/tools/pnpm-12.15.0/pnpm,可以在生成任务中这样组织:

env -u pnpm_config_pm_on_fail /opt/tools/pnpm-12.15.0/pnpm install --lockfile-only

路径是占位示例,不能照抄不存在的程序。env -u 只对本次调用移除该变量;真实环境还需核对配置文件和其他同义配置来源,避免仍把 pmOnFail 设为 ignore。不要把关闭包管理器版本管理当成项目的长期目标,实际执行版本仍应与清单 pin 一致。

该命令会修改锁文件。审查差异,确认增加的是预期包管理器文档,应用依赖没有夹带未经批准的重新解析。不要从别的项目复制 packageManagerDependencies,也不要手写猜测的 tarball、校验值或平台包。

下一次冻结安装才覆盖原失败

提交审定锁文件后,在与 CI 相同的干净环境直接以固定目标版本运行原 --frozen-lockfile 流程,确认不再要求更新包管理器记录;同时验证应用依赖和构建。维护任务成功还不能替代这一步。

相关修正在旧版本分支有过合并,但分支合并不等于已安装的 pnpm 10 收到正式补丁。更新启动程序时核对正式版本和实际路径,再用“没有锁文件、旧版切到新版”的原流程回归。回退时恢复工具与锁文件配套,不通过去掉 frozen 约束长期掩盖不一致。