关于 deps-upgrade
用于验证 JavaScript 依赖升级,并调查暂缓升级或可能移除的包。它依据锁文件差异,结合包管理器专属检查、版本说明审查及项目实际验证。
主要功能
- 01通过 Git 差异识别变更
- 02检查 peer、引擎和依赖树
- 03审查跨越版本的发布说明
- 04运行类型检查、构建和测试
- 05评估暂缓升级或未使用的包
适用场景
- 01验证一批依赖升级
- 02诊断升级后的构建或测试故障
- 03评估包升级受阻原因
- 04调查依赖项的存在理由
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ dmythro/ agent-skills --skill deps-upgrade安装后在 Claude Code 中输入/deps-upgrade确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/allowlist.mddependency-audit.mdmigrations.mdpackage-managers.mdrelease-notes.md详细介绍
依赖升级验证
升级本身很简单;证明项目仍然协调一致才是工作重点。 此技能会在选定版本后接手——通常是在运行 bun update -i -r 或同等的交互式选择后——并验证实际升级结果:通过 git 查看真实变更、检查 peer 和引擎的完整性、梳理跨越的每个版本中的破坏性变更和迁移步骤、了解值得采用的功能,并运行项目本身来执行验证关卡。它还会回答反向问题:暂缓升级的软件包能否升级,以及它为什么会出现在 package.json 中。
已针对 bun 1.3.14、npm 11.19.0、pnpm 11.21.0、yarn 4.18.0(2026-08-15,参见 references/package-managers.md 中的命令矩阵)和 gh v2.103.2(2026-10-27,读取 gh release/gh api 的结果;自 v2.102.0 起未变)。** bun 的基准版本落后于 bun-cli 技能(v1.4.4):对于命令矩阵未涵盖的标志,请以 bun-cli 为准。
适用场景
- 验证一批升级——“我升级了很多软件包,帮我验证一切”
- 评估暂缓升级的软件包——“我们能升级 X 吗?”,“是什么阻碍了升级?”
- 质疑某个依赖——“我们为什么要用 X?我们根本没用它”
- 阅读发行说明——梳理跨越的各个版本中的破坏性变更、迁移步骤和新功能
- 升级后的问题排查——更新后出现的类型、构建或测试故障
- 升级前摸底——在有人运行升级前,了解升级需要付出的代价
关键规则
- 先检测包管理器,然后只使用它对应的列。 Bun 项目全程使用
bun,pnpm 项目使用pnpm,npm 项目使用npm,yarn 项目使用yarn。其他包管理器的 CLI 可能根本没有安装;即使已安装,它也会按自己的规则解析依赖,可能生成第二个锁文件或结构不同的依赖树。此技能所需的每项功能在四种包管理器中都有原生形式——请参阅功能矩阵,因此绝不需要切换到其他包管理器。 - 通过 git 确定变更,不要依据提示推断。“我升级了很多软件包”只是起点,不是清单。锁文件差异是唯一完整的记录——它包含
package.json中看不到的传递依赖升级。 outdated报告的是版本偏差,不是兼容性。bun outdated没有报告过期依赖,只表示每个依赖都处于其版本范围允许的最新版本;它并不能说明依赖树仍能解析、构建或运行。绝不能据此声称升级已通过验证。- 生态系统软件包的 peer 范围是上限,不是注册表的
latest。 某个框架插件若将next@">=16.2.6 <17.0.0"设为上限,无论注册表将哪个版本称为最新,框架都受此限制。提出升级前,应先查看封装目标软件包的其他软件包所声明的 peer 依赖。 - peer 要求的软件包即使没有任何导入,也仍然是必需的。
graphql是[email protected]的必需peerDependency;即使应用从未编写查询,也必须声明它。提出移除建议前,先运行bun why并检查所有已安装的 peer 依赖(参见references/dependency-audit.md)。 - 未经明确批准,绝不运行迁移、代码转换工具或版本变更。 报告确切命令及其影响范围。建议数据库架构迁移前,还必须说明执行顺序和回滚方案。
- 阅读跨越的每个版本的发行说明,而不只是目标版本的说明。 如果某个破坏性变更在
16.9引入,而16.14的发行说明没有提到,那么对于从16.8升级的项目来说,它仍然是破坏性变更。 - 通过运行项目进行验证。 类型检查、构建和测试才是证据。即使变更日志承诺兼容,也不能作为证据。
- 说明未检查的内容。 跳过的软件包、未阅读的发行说明和未测试的路径都应写入报告;不作说明就会让人以为已全面检查。
功能矩阵
查看项目对应的列,不要使用其他内容。空白表示该包管理器没有此命令——备注中的替代方法仍需使用该包管理器。
| 能力 | bun | npm | pnpm | yarn(berry) |
|---|---|---|---|---|
| Registry 元数据 | bun info <pkg> [prop] | npm view <pkg> <field> | pnpm view <pkg> <field> | yarn npm info <pkg> -f <fields> |
| 安装原因 | bun why <pkg> | npm why <pkg> | pnpm why <pkg> | yarn why <pkg> --peers |
| 已安装依赖树 | bun pm ls --all | npm ls --all | pnpm list --depth Infinity | yarn info -A -R |
| Peer 依赖验证 | peer-check.ts(references/dependency-audit.md) | npm ls --all --json -> .problems | pnpm peers check | yarn explain peer-requirements <hash> |
| 安全公告 | bun audit --json | npm audit --json | pnpm audit --json | yarn npm audit --json |
| 过时依赖 | bun outdated(仅表格) | npm outdated --json | pnpm outdated --format json | -- |
| 指定范围内的版本 | bun info <pkg> versions + Bun.semver | npm view '<pkg>@<range>' version | pnpm view <pkg> versions --json + 筛选 | yarn npm info <pkg> -f versions --json + 筛选 |
| Lockfile 检查 | bun install --frozen-lockfile --dry-run | npm ci --dry-run | pnpm install --frozen-lockfile | yarn install --immutable |
| 读取 package.json | bun pm pkg get <field> | npm pkg get <field> | pnpm pkg get <field> | 读取文件 |
| 运行工具 | bunx <tool> | npx <tool> | pnpm dlx <tool> | yarn dlx <tool> |
需要注意的事项:
- Peer 依赖验证的质量差异很大。
pnpm peers check和yarn explain peer-requirements是专门为此设计的:两者都会指出提出要求的包、所需范围和已安装版本;而且pnpm peers check会以1退出,因此可用作门禁。npm 没有专用命令——npm ls --all --json会在.problems下显示"invalid: <pkg>@<ver>",而npm install --dry-run会打印完整依赖链但不写入文件。Bun 的处理最弱(只会发出不指出相关包的非致命警告),因此这里为它使用references/dependency-audit.md中的脚本。 - pnpm 和 yarn 会在安装时报告 Peer 依赖问题,因此安装输出值得查看,而不是直接丢弃:pnpm 会以
Issues with peer dependencies found结尾,yarn 会发出YN0060,指出相关包和以p开头的六字母哈希,后者可传给yarn explain peer-requirements。 - 只有 npm 能直接列出指定版本范围内的所有版本。
npm view '<pkg>@>16.8.0 <=17.0.2' version会列出所有匹配项;而bun info和pnpm view使用同一范围时,会解析为其中最高的一个版本,悄悄隐藏中间的版本。其他情况下,先列出所有版本再进行筛选。 - yarn 列对应的是 berry(v2+)。Yarn Classic 使用的是另一套 CLI。 执行任何命令前,先确认版本:如果有
yarn.lock和.yarnrc.yml,就是 berry;只有yarn.lock则是 v1。Classic 保留了 npm 风格的命令——yarn outdated、yarn info <pkg>、yarn audit --json、yarn why <pkg>(没有--peers)、yarn list,以及yarn install --frozen-lockfile(而不是--immutable)。在 v1 中运行 berry 的yarn npm info或yarn dlx会直接失败。 - Yarn berry 没有
outdated——v1 有这个命令,但在重写时被移除了,因此在 berry 中运行yarn outdated会因未知 script 而失败。在 berry 中可使用yarn dlx taze或yarn upgrade-interactive。 - Bun 的
outdated不支持 JSON。 它会接受--json,但忽略此参数。请解析表格——列为Current | Update | Latest。
按包管理器筛选指定范围内的版本:
# bun -- Bun.semver is built in, nothing to download
bun -e 'const vs = JSON.parse(await Bun.$`bun info graphql versions --json`.text());
console.log(vs.filter(v => Bun.semver.satisfies(v, ">16.8.0 <=17.0.2"))
.sort(Bun.semver.order).join("\n"));'
# npm -- native
npm view 'graphql@>16.8.0 <=17.0.2' version
# pnpm / yarn -- list, then filter with the semver CLI via that manager's runner
pnpm view graphql versions --json | jq -r '.[]' | xargs pnpm dlx semver -r '>16.8.0 <=17.0.2'
yarn npm info graphql -f versions --json | jq -r '.versions[]' | xargs yarn dlx semver -r '>16.8.0 <=17.0.2'
除非范围中指定了预发布版本,否则 Semver 范围会排除预发布版本,因此四种包管理器都会自动排除 canary 和 rc 版本,无需额外筛选。
其他工具也不能想当然地认为已安装。 这些示例会使用 jq 和 gh;它们都不是包管理器自带的工具。依赖它们之前请先检查(command -v jq gh)——此外,gh 还需要通过身份验证才能读取发布信息。没有 jq 时,可使用项目自己的运行时进行解析;没有 gh 时,可改用 WebFetch 读取发布页面。
包管理器检测
按以下顺序检查——如果两者都存在,以 packageManager 字段为准,因为 Corepack 和 CI 会强制使用它:
bun pm pkg get packageManager 2>/dev/null # or: cat package.json | grep packageManager
ls bun.lock bun.lockb package-lock.json pnpm-lock.yaml yarn.lock 2>/dev/null
ls bunfig.toml .yarnrc.yml deno.lock 2>/dev/null # bunfig.toml marks bun; .yarnrc.yml marks yarn berry
| 锁文件 | 包管理器 | 交互式升级命令 |
|---|---|---|
bun.lock(文本)或 bun.lockb(二进制) | bun | bun update -i -r |
pnpm-lock.yaml | pnpm | pnpm update -i -r -L |
yarn.lock + .yarnrc.yml | yarn berry(v2+) | yarn upgrade-interactive |
yarn.lock,无 .yarnrc.yml | yarn classic(v1) | yarn upgrade-interactive |
package-lock.json | npm | 内置命令:无——npx taze -I 或 npx npm-check-updates -i |
如果存在 deno.lock,但没有 npm 锁文件,则这是一个 Deno 项目:以上四列均不适用,以下各阶段仍然适用(参见 references/package-managers.md)。请明确说明,而不要猜测包管理器。
工作区会改变每条命令的形式:单体仓库需要使用递归或筛选形式,并且每个工作区的 package.json 都会纳入差异范围。
参考:完整且已验证的各包管理器命令矩阵,请参见
references/package-managers.md。
阶段 0:确定差异
在此之前,其他任何结论都不可信。
# Declared changes (root + workspaces)
git diff HEAD -- package.json '**/package.json'
# Resolved changes, including transitive bumps nothing declared
git diff HEAD -- bun.lock # or pnpm-lock.yaml / yarn.lock / package-lock.json
# Already committed on a branch
git diff origin/main...HEAD -- package.json '**/package.json' bun.lock
对每项变更进行分类,因为升级类型决定了需要多严格地审查:
| 变更 | 风险 | 处理方式 |
|---|---|---|
主版本(1.x -> 2.x) | 高 | 完整阅读发行说明、查找迁移指南、扫描功能变更 |
0.x 次版本 | 高 | Semver 在 1.0 之前不保证兼容性——按主版本变更处理 |
| 预发布版 / rc / canary | 高 | 确认这是有意为之;检查是否误用了 --latest |
次版本(1.2 -> 1.5) | 中 | 扫描说明,查找 BREAKING、deprecat、removed、migrat |
| 补丁版本 | 低 | 跳过说明,除非它是直接运行时依赖或安全修复 |
| 仅传递性依赖(锁文件) | 中 | 无需阅读说明;确认依赖树仍可解析,且没有任何依赖跨越主版本 |
| 范围扩大,版本不变 | 低 | 记录此变更——下一次安装可能在不修改代码的情况下漂移 |
二进制锁文件不会产生可读差异。 对于 bun.lockb,可以使用 bun pm ls --all 在前后分别保存已解析的依赖树快照并进行比较;也可以将项目一次性转换为自 Bun 1.2 起默认使用的文本锁文件:
cp bun.lockb /tmp/bun.lockb.bak # keep the original
bun install --save-text-lockfile --frozen-lockfile --lockfile-only # rewrites the lockfile only
--frozen-lockfile --lockfile-only 可确保转换只是重新编码:不会解析锁文件中未固定的版本,也不会触碰 node_modules。如果不加这两个参数,同一命令可能会解析到新版本,从而改变所测量的差异。
转换后会保留 bun.lockb,是否删除由用户决定,而不是清理步骤——如果新的 bun.lock 有误,它是唯一保留原解析结果的副本。先验证转换后的文件(bun install --frozen-lockfile --dry-run 能成功执行,并且解析出的版本与转换前 bun pm ls --all 的快照一致),然后再征求用户同意后执行 rm bun.lockb。
在据此得出任何结论之前,请确认工作树与锁文件一致:
bun install --frozen-lockfile --dry-run # bun -- validates, writes nothing
npm ci --dry-run # npm -- validates, writes nothing
pnpm install --frozen-lockfile --lockfile-only # pnpm -- validates without linking
yarn install --immutable # yarn -- validates, but installs
Bun 和 npm 提供真正的试运行:如果 package.json 与锁文件不一致,两者都会失败,且都不会修改磁盘。pnpm 将工作拆分开来——pnpm install --dry-run 会预览安装将进行的更改,但不会写入任何内容;而 --frozen-lockfile 用于验证,并会作为副作用执行安装;与 --lockfile-only 搭配使用时,可在不链接 node_modules 的情况下进行检查。Yarn 在此处没有试运行选项:yarn install --immutable 会在检测到漂移时立即失败,并在此过程中执行安装,因此仅在可以接受安装的环境中运行。
阶段 1:静态完整性
在阅读任何发布说明之前,先运行这些检查——它们成本低,而且能发现变更日志不会提醒你的问题。
同级依赖冲突(最有效的检查)。 使用你的包管理器的:
pnpm peers check # names package, wanted range, installed version; exits 1
yarn explain peer-requirements <hash> # hash comes from the YN0060 line in install output
npm ls --all --json | jq '.problems' # "invalid: <pkg>@<ver>"; npm install --dry-run for the full chain
bun run peer-check.ts # see references/dependency-audit.md
Bun 需要用脚本检查。它会将违反范围的情况报告为 warn: incorrect peer dependency "[email protected]"——这不是致命错误,不会指出任何依赖,也不会出现在任何机器可读的输出中:
$ bun run peer-check.ts
CONFLICT [email protected] needs graphql@^0.9.0 || ... || ^16.0.0 -- installed 17.0.2
npm 的普通 npm ls 同样会造成误导——在深度为 0 时,即使依赖树中的同级依赖无效,它也会以退出码 0 将其显示为正常,因此必须使用 --all --json。
引擎要求与实际使用的运行时:
bun info <pkg>@<ver> engines # npm view / pnpm view / yarn npm info -f engines
bun --version; node --version
升级引入的弃用项:
bun info <pkg>@<ver> deprecated || echo "not deprecated"
未弃用的包没有此属性,而 bun info 会将缺少的属性视为错误:error: Property deprecated not found,退出码为 1。这才是正常情况——不要将其报告为查询失败。对于同样的情况,npm view 和 pnpm view 不会打印任何内容,且退出码为 0。
依赖树中的重复主版本——同一个有状态库(React、GraphQL、ORM 客户端)出现两个副本是运行时错误,而不是体积问题。请使用矩阵中的 Why-installed 和 Installed-tree 行:
bun why <pkg> --depth 3 # pnpm why / npm why / yarn why --peers
bun pm ls --all # pnpm list --depth Infinity / npm ls --all / yarn info -A -R
升级后的安全态势:
bun audit --json | jq 'to_entries[] | {pkg: .key, advisories: [.value[] | {severity, title, vulnerable_versions}]}'
bun pm scan # bun only: lockfile scan, no installed tree needed
npm audit --json、pnpm audit --json 和 yarn npm audit --json 会用各自不同的输出格式回答同一个问题——编写筛选器之前,先了解输出格式。
类型包版本对齐——@types/* 的主版本应与其运行时包的主版本一致。版本不匹配会在阶段 6 导致类型错误,而不是安装失败,因此请在差异表中将它们配对。
参考:请参阅
references/dependency-audit.md,了解同级依赖上限检查方法、重复主版本诊断和移除决策树。
阶段 2:发布说明
根据阶段 0 的风险列安排此阶段的时间。获取每个传递依赖补丁版本的说明会耗费上下文,还会掩盖重要发现。
bun info <pkg> repository # npm view <pkg> repository.url / pnpm view / yarn npm info -f repository
bun info <pkg> homepage # docs site, where upgrade guides live
gh release view v17.0.0 --repo <owner>/<repo> --json tagName,publishedAt,body
使用能力矩阵中与你的包管理器对应的行,列出跨越的每个版本。只有 npm 可以直接接受版本范围;使用 bun 和 pnpm 时,<pkg>@<range> 会解析为符合条件的最高版本(bun info 'graphql@16' version 会返回 16.14.2),并悄悄隐藏其间的所有版本。
按来源顺序查找,从成本最低的开始:node_modules/<pkg>/CHANGELOG.md(免费,文件已在本地,但许多包没有提供)-> gh release view -> 仓库中的 CHANGELOG.md / UPGRADING.md / MIGRATION.md -> 通过 WebFetch 获取文档站点上的升级指南。
只提取四项内容:破坏性变更、迁移步骤(包括移除版本的弃用项),以及可替代项目中现有手写代码的新增功能。其他内容都是噪声。
参考:请参阅
references/release-notes.md,了解仓库定位、标签命名回退策略、单体仓库处理和gh用法。
阶段 3:迁移
发布说明常常把迁移要求埋在行文中,而两种迁移的失败方式各不相同:
- 代码迁移——代码修改工具、重命名 API、配置移动或结构调整。失败时明显且影响局部:构建会中断。
- 架构和数据迁移——ORM 或 CMS 模型变更,需要生成并提交迁移,然后按照特定顺序相对于部署应用。开发环境中的失败不易察觉,在生产环境中则可能造成破坏。
这两类迁移都会附上确切命令、标明是必须立即执行还是可选;对于架构迁移,还会附上执行顺序和回滚说明。未经批准,不会执行任何迁移。
参考:请参阅
references/migrations.md,了解检测模式、各生态系统的命令和部署顺序。
阶段 4:暂缓升级和可疑的包
对于用户未升级或怀疑不需要的每个包,都要明确回答以下两个问题:
- 为什么会有这个包? 直接依赖且有导入 / 因为某个对等依赖需要它才作为直接依赖 / 仅为传递依赖但声明有误 / 确实未使用。
- 是什么阻止了升级? 指明限制其版本的包和对等依赖范围,或者说明没有阻碍,可以升级。
绝不能仅凭导入检索结果回答第一个问题——这正是导致必需的对等依赖被删除的原因。
参考:完整的决策树请参阅
references/dependency-audit.md。
阶段 5:可采用的功能
根据阶段 2 收集的笔记,列出项目可以采用的功能,并按其能移除的内容排序:优先列出可替代手工实现的变通方案,其次是可移除依赖的功能,然后是性能和 DX 方面的功能。提出建议前,先确认项目中确实存在要替代的模式——检索旧 API。这些都是提案,并附带工作量估算,绝不是修改。
阶段 6:验证关卡
从成本最低的开始,遇到第一个失败就停止,并在继续前说明失败归因:
bun install --frozen-lockfile # npm ci / pnpm install --frozen-lockfile / yarn install --immutable
bun run typecheck # or: bun --check (Bun >= 1.4.3, never runs a "check" script), bunx tsc --noEmit
bun run lint
bun run build
bun test # or the project's own test script
全程替换为项目使用的包管理器运行命令(npm run、pnpm、yarn)。注意,bun test 是 Bun 自带的测试运行器:如果项目使用 Jest 或 Vitest,验证关卡应为 bun run test,它会执行项目的脚本。请从 package.json 中读取实际的脚本名称,不要想当然;跳过项目未定义的关卡,并说明这一点。然后进行运行时冒烟检查——启动开发服务器,访问一个能执行升级后包的路由或入口点。代码通过类型检查和构建检查,仍可能在运行时因初始化、配置架构和适配器 API 的变更而失败。
将每个失败归因到导致它的包。“构建失败”不是一项发现;“构建失败,因为配置选项在 16.0 中更名”才是。
阶段 7:报告
先给出表格,然后列出需要决策的部分:
| Package | Old -> New | Bump | Risk | Breaking | Migration | Action |
|---------|-----------|------|------|----------|-----------|--------|
| next | 15.4.2 -> 16.3.1 | major | high | yes | codemod | run codemod |
| graphql | 16.8.0 (held) | -- | -- | -- | -- | blocked by payload peer ^16.8.1 |
然后,仅在内容非空时列出:受阻(限制每个暂缓升级包的因素)、需要采取行动(迁移和代码更改,并附命令)、采用(可选功能和工作量)、移除(有证据证明不需要的依赖)、安全(已解决或新增的安全公告)、未检查(跳过的包和未测试的路径)。
提交说明应描述实际更改,而不是产生更改的过程——使用 fix: update config for renamed option,而非 fix: post-upgrade fixes(参见 git-commit 技能)。
关键注意事项
- 未检测到的包管理器可能并未安装——即使已安装,它也会按自身规则解析,并可能留下第二个锁文件。并非每台安装了 bun 的机器上都有
npm。四种包管理器都为每项功能提供原生形式(功能矩阵);没有必要跨管理器操作,而且这样做往往并非无害。同样需要注意的是jq和gh,它们不会由任何包管理器安装。 bun outdated没有 JSON 输出(截至 1.3.x)——--json会被静默忽略,仍然会打印表格。解析表格(Current | Update | Latest),不要为此改用其他包管理器。bun info在项目外会失败——包括普通的注册表查询,都会报错:error: Bun could not find a package.json file to install from。在项目内,它才是正确的工具。bun info <pkg> deprecated在包状态正常时会报错——error: Property deprecated not found,退出码为1。对bun info来说,属性缺失就是错误,因此正常结果看起来像命令失败。应根据消息而非退出状态进行判断(npm view不输出任何内容,退出码为0)。bun info '<pkg>@<range>' version返回的是一个版本,而非版本范围——它会解析到符合条件的最高版本,悄悄隐藏中间的所有版本。应使用bun info <pkg> versions列出版本,再通过Bun.semver.satisfies进行筛选。Bun.Glob的花括号选项中不能包含/——{*,@*}/package.json可以正常匹配,但{*,@*/*}/package.json什么也匹配不到,也不会报错,因此扫描node_modules时会静默返回零个包,所有基于此的检查都会报告成功。每种形状使用一个模式。点目录也有同样的静默归零问题:除非传入dot: true,否则scan看不到node_modules/.bun和node_modules/.pnpm。- 各包管理器在报告对等依赖冲突方面的差异最大——
pnpm peers check会列出包、版本范围和已安装版本,并以退出码1结束;yarn 会在安装时打印YN0060,并附带供yarn explain peer-requirements使用的哈希;npm 需要使用npm ls --all --json->.problems或npm install --dry-run;bun 只会发出不指出具体包的非致命警告。不要以为某个包管理器的报告质量在其他包管理器中也一样。 npm ls在深度为 0 时会隐藏对等依赖无效的问题——即使树中违反了对等依赖范围,它也会干净地输出并以退出码0结束。应使用npm ls --all --json | jq '.problems'。仅限 npm 项目:npm install --dry-run不会写入任何内容(已验证——不会出现package-lock.json),并会打印完整的依赖要求链。- bun 会将横幅写入 stderr,将数据写入 stdout——
bun audit --json | jq可以直接通过管道处理;无需清理输出。 dist-tags可能受到污染——有些包带有数十个 canary 和实验性标签。读取dist-tags.latest,不要读取第一个条目。- 发布标签命名不一致——可能是
v17.0.2、17.0.2、使用包标签的 monorepo 中的@scope/[email protected],也可能是包含版本之外内容的发布名称(React 将标签v19.2.8的名称设为19.2.8 (July 21st, 2026),因此名称匹配会失败,而tagName匹配有效)。应逐级尝试解析,不要猜一次就放弃。 - 充斥着 canary 版本的仓库会淹没发布列表——
gh release list --repo vercel/next.js返回的大多是预发布版本;请传入--exclude-pre-releases。 repository.url可能指向已重命名的组织——React 的元数据显示为github.com/react/react。gh会跟随重定向,因此应直接传入,不要手动验证。- 许多包在任何地方都没有变更日志——tarball 中没有,monorepo 根目录中也没有。这种情况下,GitHub 发布记录是唯一来源;少数包则要查看文档站点。
- Yarn berry 没有
outdated命令——该命令未从 v1 沿用,yarn outdated会被识别为未知的脚本,而非未知命令。请使用yarn dlx taze或yarn upgrade-interactive。 - 传递依赖的升级永远不会出现在
package.json中——供应链事件或嵌套依赖中的破坏性变更,只能通过锁文件差异看出来。 - 同一天发布的版本值得再检查一次——
bun info <pkg> time --json会列出每个版本的日期。现在每个包管理器都提供了冷却期功能,正是出于这个原因(bun install --minimum-release-age=<seconds>、npm install --min-release-age=<days>、pnpm 的minimumReleaseAge设置、yarn 的默认时间门槛),所以某个版本若被工具拒绝选用,可能是有意暂缓,而非版本有问题。 knip等未使用依赖工具会将被对等依赖要求的包标记为未使用——这正是关键规则 4 要防范的陷阱。应将其输出视为待调查的候选列表,而非待移除列表。- 锁文件漂移会在升级完成后持续存在——扩大版本范围却不更改已安装的版本,意味着下次全新安装时解析出的版本会不同。即使表面上没有变化,也应标出仅修改版本范围的改动。
参考:按包管理器分类的命令矩阵请参阅
references/package-managers.md参考:版本说明和变更日志的获取方法请参阅references/release-notes.md参考:代码转换工具和架构迁移请参阅references/migrations.md参考:对等依赖上限和依赖项说明请参阅references/dependency-audit.md参考:自动批准模式请参阅references/allowlist.md