mcpField
A
antfu-simplify

antfu-simplify

github.com/antfu开发6.0k137 次安装3 天前更新
代码仓库

关于 antfu-simplify

用于精简当前 PR 或工作区差异的代码审查技能,目标是在不改变行为的前提下保留最小且正确的改动。它分批验证删除内容,并报告保留或删减的部分、差异规模及检查结果。

主要功能

  1. 01审查当前变更差异
  2. 02移除冗余或推测性内容
  3. 03保持行为和范围不变
  4. 04每批改动后运行检查
  5. 05报告取舍及差异规模

适用场景

  1. 01精简 PR 中的抽象层
  2. 02判断新增分支或辅助函数是否必要
  3. 03审查前缩减工作区改动

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/antfu/skills --skill antfu-simplify

安装后在 Claude Code 中输入/antfu-simplify确认已加载。

详细介绍

精简变更

审查当前变更(PR 分支或工作区),并像熟练的开发者那样,将其精简为最小且正确的差异。采用消融研究的方法:逐项移除,检查是否会破坏重要功能,只保留真正有必要的部分。

目标:代码整洁、精简,抽象程度恰到好处,同时稳健(能处理实际边界情况)且通用(解决一般情况,而不只是触发此次变更的特例)。

硬性规则

  • 行为保持不变。 只做精简。不要添加功能、修改公共 API 或修复无关问题。应单独报告无关发现。
  • 范围仅限差异。 只修改此次变更新增或修改的代码,以及移除这些代码所必需修改的部分。不要重构周边代码库。
  • 每项移除都要验证。 每批修改后运行仓库的测试、类型检查和代码检查。如果某项检查没有覆盖被移除的部分,就明确分析原因,否则保留该部分。
  • 遵循周边代码的风格、命名和注释密度。

工作流程

  1. 获取差异。 确定基准:优先使用 PR 目标分支的合并基点(git merge-base HEAD origin/<default>);否则,对未提交的改动使用 git diff HEAD。阅读完整差异及相关文件。用一句话记录变更目标;之后所有判断都以此为准。
  2. 盘点各部分。 列出差异新增的每个单元:函数、参数、选项、分支、类型、文件、依赖、抽象层、注释、测试。参见消融研究。
  3. 逐项消融。 尝试移除、内联或合并每个部分。根据保留还是删减决定取舍。
  4. 应用删减。 分小步进行。每批修改后运行针对性检查(测试、类型检查、代码检查)。如果删减导致行为异常,就撤销;这说明该部分确有必要。
  5. 检查结果。 以审查者的视角重新阅读最终差异。剩下的每一行是否都能用那句目标说明?代码是否仍然稳健且通用?
  6. 报告。 用简短表格列出删减或保留的内容及原因,并提供修改前后的差异规模(git diff --stat)。除非有人要求,否则不要提交。

消融研究

对差异中的每个部分,都要问:如果删除它,具体会有什么损坏?

部分消融操作保留条件
新函数 / 辅助函数在调用处内联被 2 个或更多位置调用,或其名称说明了不明显的步骤
包装器 / 抽象层直接调用底层内容它隐藏了实际复杂性,或隔离了可能变化的边界
参数 / 选项 / 配置将唯一使用的值硬编码现有调用方确实需要使用不同的值
类型 / 接口 / 泛型使用推断类型或现有类型它已导出,或类型推断会导致更差或错误的类型
分支 / 守卫 / try-catch删除并运行测试它防护的是可达情况(真实输入、真实故障),而非不可能发生的情况
新文件 / 模块合并到唯一的使用方中它有多个使用方,或职责独立
依赖改用几行代码或现有依赖它能处理否则很容易出错的边界情况
重复逻辑复用仓库中已有的工具函数仓库中不存在等效实现(先搜索)
注释删除它说明的是为什么(限制、变通方案、令人意外的选择),而不是是什么
测试删除并检查哪些行为失去了保护它覆盖了其他测试都未覆盖的行为或回归问题
与目标无关的修改行还原绝不保留顺手改动

保留还是删减

在以下情况下删减:

  • 推测性的:为没人需要的未来需求而构建(额外选项、钩子、插件扩展点、“以防万一”的泛型)。
  • 冗余的:重复了语言、框架、类型或现有工具已经提供的功能。
  • 防范不可能发生的情况:对类型或调用方保证的值进行空值检查、永远不会执行的回退逻辑、吞掉错误的 catch 块。
  • 没有收益的间接层:只用一次的辅助函数、透传包装器、明明函数就能完成的类、只能构建一种东西的工厂。
  • 噪音:注释掉的代码、叙述性注释、未使用的导入和导出、仅涉及格式的改动。

在以下情况下保留(或适当增加):

  • 健壮性: 处理真实的边界情况(空输入、并发、清理、跨平台路径、附带上下文的错误传播)。
  • 通用性: 解决一般问题,而不是只针对报告的问题做特殊处理。如果修复将问题报告中的名称、路径或值写死,就应将其泛化。
  • 恰到好处的抽象: 某种内容重复到第三次时再提取;第一次和第二次通常不必。好的抽象能删掉比自身增加的代码更多的代码。

如果抽象太小,就合并;如果函数做了几件互不相关的事,就拆分。目标既不是行数最少,也不是层数最多,而是让读者需要掌握的概念尽可能少。

需要留意的问题

  • 在调用处修补症状,而不是解决根因。
  • 存在通用规则即可覆盖的特殊情况(if (name === 'foo'))。
  • 两条代码路径做着相同的事,只存在细微差异;应将它们统一。
  • 可以从现有数据推导出的状态、标志或缓存。
  • 参数列表过长,或选项对象中的大多数值从未改变。
  • 可以通过 typeof、ReturnType、Parameters 或工具类型推导,却仍手动重复定义的类型。
  • 仓库、运行时或现有依赖已经提供,却仍手动实现的工具函数。
  • 断言实现细节或逐行复刻代码的测试。

报告格式

| # | Piece | Action | Why |
|---|-------|--------|-----|
| 1 | `parseOptions()` in src/cli.ts | inlined | one caller, 3 lines |
| 2 | `retry` option | removed | no caller passes it; default is enough |
| 3 | `try/catch` in fetchData | kept | network errors reach users; test covers it |

Diff: +142 -8 -> +61 -8. Tests, typecheck, lint pass.

将发现但不在本次范围内的问题(无关的 bug、更大范围的重构)单独列出,并暂不处理。

评论

支持 Markdown