依赖升级最怕一次改太多。让 Codex 先识别项目使用 npm、pnpm、Yarn 还是别的包管理器,确认仓库里的锁文件和运行时版本,再决定要动哪一个包。
先看差距,再选批次
在 npm 项目里,npm outdated 会列出当前安装版本、符合现有版本范围的 wanted,以及发布渠道上的 latest。两者相差一个主版本时,升级范围已经可能包含破坏性变化。pnpm 项目可以用对应的 pnpm outdated 查看差距。命令、参数和输出会随包管理器版本变化,执行前应以项目实际版本的官方帮助为准。
先记录当前分支、干净状态、Node 版本、包管理器版本和基线测试结果。随后读目标包的官方发布说明、迁移指南与运行时要求。一个批次只处理关系紧密的依赖,框架、测试工具和构建器最好分别更新,失败时才容易定位。

锁文件和代码要一起审
使用项目原有包管理器更新指定依赖,保留由它生成的锁文件。不要手改锁文件,也不要在一次任务里混用 npm 与 pnpm。检查 package.json 的版本范围、锁文件的实际解析版本、安装脚本变化,以及升级后新增或移除的间接依赖。
npm 官方把 package-lock.json 定义为可复现依赖树的一部分,并建议提交到版本库。npm ci 要求清单与锁文件一致,遇到不一致会直接失败,也不会改写清单或锁文件。它适合在干净环境和 CI 中复查升级结果。

按风险顺序验证
先跑目标包直接影响的测试,再跑类型检查、完整测试和生产构建。前端依赖还要打开关键页面检查控制台、网络请求和主要交互。服务端依赖要核对启动、配置读取、数据库连接和错误路径。测试通过以后,再用全新安装复查锁文件能否独立还原环境。
npm audit 会根据已知安全公告检查依赖树。它能提供风险线索,不能证明升级后行为兼容。npm audit fix --force 可能越过原有版本范围并安装主版本更新,使用前必须先看 dry run 和差异,随后重新执行完整验证。

为失败准备清楚的退路
升级前保留一个干净提交,随后让依赖改动独占一次提交。失败时先读第一处错误,确认来自运行时要求、peer dependency、类型声明还是业务行为。不要用删除锁文件和重新安装碰运气,那会同时改变大量间接版本,原来的比较基准也没了。
主版本升级可以先建立兼容分支。用 npm view <包名> version engines peerDependencies 核对发布信息,再按官方迁移指南处理弃用项。每解决一类错误就运行相关测试,保持差异能被单独审查。若升级需要改 Node 版本,CI、部署环境和本地版本文件必须一起更新。
回退时恢复依赖清单、锁文件与适配代码三部分,再执行干净安装和基线测试。只有版本号退回,锁文件仍留着新解析结果,环境依然可能与升级前不同。
最终提交应当只包含选定依赖、必要适配代码、锁文件和相关测试。把升级前后版本、执行过的命令、仍未处理的公告写进交付说明,下一次升级就有清楚起点。