AI 依赖升级工作流:CHANGELOG 映射 + 防漂移修复

用 Claude Code 或 Cursor 升级依赖,避免微妙的隐藏破坏。

升级依赖总挂在同样几个地方:类型检查看不见的废弃 API、函数签名没动但行为变了、peer-dep 冲突静默解析成错误版本、单测抓不到的运行时回归。AI Agent 能搞定——前提是你给它结构:CHANGELOG、对应到你代码的破坏性变更清单、以及一个”不许漂移到重构”的修复循环。

这篇主要解决什么问题

接手项目时关键依赖已经落后 12 个 major;或者周五下午 5 点掉了安全公告,patch 隐藏在两个破坏性版本之后。CI 绿但你不信版本锁。这套流程让一个开发者加一个 AI Agent,在一次专注会话里安全完成升级——并 ship 一份 CHANGELOG 映射好的 diff,reviewer 真能核。

这篇适合谁看

面对”已经落后 12 个 major”的维护者;被 npm update 烫过、现在拒绝跑它的人;接手 4 年没动过 lockfile 的内部项目的开发者;安全驱动的一次性升级、patched 版本比你领先 2 个 major 的情况。

什么时候适合用

某个依赖落后好几个 major。CI 通过但你不信版本锁。被安全公告逼着升。接手一个废弃内部工具且 lockfile 比公司当前 ESLint 配置还老。在动其他东西之前先跑这套。

什么时候不建议用

框架级迁移(Vue 2→3、React 17→19、Angular major-major、Rails major-major)——要专门的迁移计划,含 codemod、分阶段上线、常需 feature freeze,不是简单升级。也别用在小型 prototype——按当前版本从零重建比升级还快。

开始前准备

  • 确认 main 上 CI 绿。main 红就先修红,否则升级失败和既有失败混在一起没法分。
  • 准备能跑的冒烟测试方案:3-4 条手工路径,覆盖你要升的依赖。类型过 / 冒烟挂——后者抓真回归。
  • 定升级边界:就这一个包 + 必要的 peer-dep?还是带相邻包?默认”一次一个包”。
  • 留好回滚:老 lockfile 留备份,懂自己的分支保护。

具体步骤

  1. 从绿 main 拉分支。 跑完整测试套件。基线确认过。基线绿不了——先停下修基线。
  2. 和 AI 一起读 CHANGELOG。 Prompt:“我要把 \{包\}\{x\} 升到 \{y\}。读该范围的 CHANGELOG 和迁移指南。列每条可能影响 TypeScript 代码库 + [列出你用的 API] 的破坏性变更。“存清单。
  3. 破坏性变更映射到你代码。 每条问:“本仓库哪些文件用了受影响的 API?给 file:line。“点开核——给一堆没真匹配的文件就是幻觉。
  4. 升级包。 npm install package@y 或等价。重新解析 lockfile。同一次 commit 别动其他依赖。
  5. 跑测试。归档失败。 先别修。列出每个失败:哪个测试文件、哪条 assertion、源码哪一行。
  6. 失败和破坏性变更清单交叉对照。 每个失败该对应清单上一条。对不上说明你漏了一条——回第 2 步,把失败当证据重 prompt。
  7. 逐条修。 每个修复 AI 该出最小化 diff,采用新 API,不是顺手重构周边。问:“这是最小化改动,还是在引入不匹配代码库其他风格的新模式?”
  8. 跑完整测试 + 跑起来手工冒烟。 类型过不够。启动 App、走冒烟路径、看 network 和 console 警告。
  9. 按 CHANGELOG 映射写 commit。 每个 commit 写明对应清单上哪一条。Reviewer 能拿 diff 对 CHANGELOG。

破坏性变更映射 prompt

Package: \{name\}
Upgrade: \{from-version\} -> \{to-version\}
Codebase: TypeScript 5, Node 22, [framework]

读该范围的官方 CHANGELOG 和迁移指南。

返回表格:
| 破坏性变更 | 受影响 API | 本仓库 file:line | 建议修法 |

只列影响本代码库的;我们没用的特性变更跳过。每行给出
CHANGELOG 章节引用,我要能核。

第一次实操怎么跑

  1. 挑一个落后 1-2 major 的依赖。不是最危险那个。
  2. 9 步走完。
  3. 给跑时计时。记下 AI 哪一步对、哪一步需要重 prompt。
  4. 第二次跑更危险的依赖快得多——你已经知道你 Agent 每步的可靠度。

完成后检查

  • 你失败清单里每一条都对应某条 CHANGELOG 吗?对不上说明还有没发现的破坏性变更。
  • 是在跑起来的 App 上冒烟过吗,不是只 CI?类型检查抓不到运行时回归,尤其是静默那种(日志变化、默认参数翻转)。
  • AI 顺手加了无关重构吗?revert——属于另一个 PR。
  • lockfile 解析干净,还是带了某个未授权的传递依赖 major?需要就 pin 住。

怎么复用这套流程

  • 破坏性变更映射 prompt 存模板;只换包名和版本范围。
  • 每个项目维护升级日志:哪些包、哪些版本、什么失败、用了多久。规律会浮现——某些包在某个版本切换上稳定地难。
  • patch 级升级让 Dependabot / Renovate 自动 PR;这套手动 AI 流留给 major 和高危 minor。

建议的操作流程

React Router 5 → 6:列破坏性变更(SwitchRoutesuseHistoryuseNavigate 等)→ 升级 → 11 个测试挂 → 每个挂对应一条已知破坏性变更 → 上线。如果 App 部署到 Firebase Hosting,紧接着跑AI Firebase 部署检查工作流——大版本升级常常会打坏 SPA rewrite 规则和 function region,本地测试抓不到。

容易踩的坑

  • 跳过 CHANGELOG。AI 会从训练数据猜——可能对你的版本不对。一定要把 Agent 锚在已发布的 CHANGELOG 上。
  • 升级时让 AI 顺手做风格重构。每个重构都给本应无聊的 PR 增加风险。留给另一波。
  • 同时升多个包。失败归因难。一个包一个 PR。
  • 不在跑起来的 App 上冒烟。类型过,App 加载空白因为一个默认 prop 翻了。冒烟不可选。
  • 信任传递依赖解析。lockfile 引入新 major 的传递包就显式 pin 直到你也读过它的 CHANGELOG。
  • CI 绿就算完。生产有 CI 不复现的运行时配置——先上 staging。

进阶技巧

  • 框架升级问:“\{x\}\{y\} 的官方推荐迁移路径?维护者发布的 codemod / 迁移脚本?“用上。
  • peer-dep 地狱问:“最小兼容版本集合一起升哪些?“作为协调单元升,不是零碎升。
  • 反复痛的包,建一份过去修复 snippet 库。很多包跨 major 复用同样的破坏性变更模式。
  • monorepo:先在最小 workspace 升一次摸形状再传播。

怎么验收输出

  • 从绿 main 拉的分支,所有测试基线过。
  • CHANGELOG 破坏性变更映射到具体文件。
  • 所有测试挂都对应一条已知破坏性变更。
  • 运行中的 App 手动冒烟过。
  • 升级 commit 里没掺风格重构。
  • lockfile 审过并提交。

FAQ

  • 也用 Dependabot 吗?: 用——补丁版升级和 minor 让它做。AI 流程在 major 和高危 minor、已知有迁移痛点的包上发挥。
  • 废弃警告怎么办?: 当作作业,不是阻塞项。2-4 周内单独排 PR 清。让 deprecation 堆积会变成下一个”落后 12 个 major”问题。
  • 传递依赖怎么处理?: 升级后审 lockfile。某个传递跳了未授权的 major,显式 pin 或 override。
  • AI 坚持某条破坏性变更和你无关、但其实有关怎么办?: 把失败测试输出给它,问:“把这个失败和你说不适用的 CHANGELOG 条目对齐。“Agent 在被指出矛盾时会自纠。
  • 能多 Agent 并行吗?: 同一分支一次一个 Agent。同一升级里并行 Agent 会冲突且丢失 CHANGELOG-到-失败的追溯。
  • npm、pip、cargo、gem 都适用吗?: 都适用。CHANGELOG 锚定步骤语言无关;只是安装命令和测试框架细节不同。

相关阅读

标签: #AI 编程 #教程 #工作流