large-repo-refactor
Skill7 starsChanged 5 months agoMITView on GitHub
在大型存量代码库做重构时使用。控制影响面,小步推进,不破坏现有行为。
In this repository47 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- api-designSkill
- chinese-commitSkill
- ci-cd-pipelineSkill
- cocos2dx-luaSkill
- cocos-creator-adaptationSkill
- cocos-creator-bundleSkill
- cocos-creator-drawcallSkill
- cocos-creator-hotupdateSkill
- cocos-creatorSkill
- cocos-creator-tween-animSkill
- cocos-creator-ui-listSkill
- code-review-selfSkill
- concurrency-safetySkill
- core-disciplineSkill
- database-safetySkill
- docker-best-practicesSkill
- domestic-stackSkill
- error-handlingSkill
- frontend-best-practicesSkill
- game-assets-memorySkill
- game-mathSkill
- game-netcodeSkill
- game-performanceSkill
- gameplay-architectureSkill
- godot-gdscriptSkill
- go-idiomsSkill
- input-validationSkill
- integration-testingSkill
- legacy-safe-editSkill
- naming-thingsSkill
- node-best-practicesSkill
- performance-profilingSkill
- pr-descriptionSkill
- python-idiomsSkill
- requirement-deliverySkill
- rust-safetySkill
- secrets-handlingSkill
- security-reviewSkill
- shell-scripting-safeSkill
- systematic-debuggingSkill
- test-data-managementSkill
- test-drivenSkill
- unity-csharpSkill
- unreal-cppSkill
- writing-docsSkill
The file
Files
大仓库重构
何时用
- 需要对大型或老代码库做结构性调整:抽函数、移动模块、重命名、拆分大文件。
- 已有功能运行正常,但代码组织混乱、可读性差,需要在不改变外部行为的前提下清理内部结构。
- 接到"把这个模块重构一下"或"把这些文件整理整理"的任务,改动会波及多个文件或多处调用方。
- 团队准备迁移到新架构,需要分阶段、可回退地把现有代码逐步搬过去。
核心规则
1. 先立测试护栏
规则: 确认关键路径有测试覆盖再动手重构;若测试不存在或覆盖不足,先补特征测试(characterization test)锁住当前行为,再开始结构调整。
为什么: AI 做重构时最常见的事故不是"改错了逻辑",而是"改完觉得没问题,其实已经悄悄改变了行为"。没有测试护栏,重构后的代码和重构前的代码在输入输出上是否完全一致,只能靠肉眼比对,这在大仓库里几乎不可能做到。特征测试的目的不是验证"代码应该做什么",而是记录"代码现在实际做什么"——包括那些可能是 bug 的行为,先把它们冻结下来,重构完再讨论要不要修。
怎么做:
- 重构前先跑现有测试套件,确认全部通过,建立基准绿灯。
- 找出重构目标的关键输入输出(函数签名、HTTP 响应、数据库写入格式),用现有输出写断言,不是写"预期应该怎样"而是写"现在实际是怎样"。
- 特征测试不需要优雅,只需要覆盖:把现有行为的真实输出直接复制进断言,宁可多写几个边界用例。
- 补完测试,跑一遍确认全绿,再切到重构任务。
2. 行为不变原则
规则: 重构只允许改代码结构,不允许同时改外部可见行为;每完成一个重构步骤立刻跑测试,确认行为与改前完全一致。
为什么: AI 在重构时极容易把"顺手改进逻辑"和"结构调整"混在一起——改参数顺序"因为这样更合理",修掉一个"顺眼的边界条件",调整返回值结构"更符合最佳实践"。每一处单独看都是好意,但混在重构里有两个危险:一,下游调用方可能依赖这个"不合理"的行为;二,一旦测试挂掉,无法判断是结构改动破坏的还是逻辑改动破坏的。重构和行为修改必须是两次独立的提交。
怎么做:
- 每个重构步骤结束后立刻跑测试,不要攒几步再跑。
- 若发现现有代码有 bug 或值得改进的逻辑,记录下来,不在当前重构 PR 里动,单独开任务处理。
- 提交信息中明确写"refactor: 只改结构,行为不变",让 reviewer 知道这一步不含逻辑变更,可以用更轻量的方式审查。
- 若测试挂掉,先还原到上一步绿灯状态,找出哪一处结构改动影响了行为,再修正,不要在挂掉状态下继续推进。
3. 单一变换,每步可独立回退
规则: 每次提交只做一种重构操作——改名就只改名,抽函数就只抽函数,移动文件就只移动文件;绝不在同一个提交里混合多种变换。
为什么: AI 被要求"重构这个模块"时,会倾向于一口气生成"改完的最终状态":函数名换了、目录结构调了、逻辑抽象层加了、import 路径更新了——全在一个 diff 里。这类大爆炸式提交在代码 review 时几乎无法有效审查,出问题时更无从用 git bisect 定位。出了问题只能整体回滚,等于白做。单一变换的核心价值是:每一步都可以被精确撤销,问题定位可以缩到一次提交粒度。
怎么做:
- 把重构计划拆成操作列表,每条对应一个提交:
步骤 1: 把 processOrder 里的金额计算逻辑抽成 calculateAmount 函数 步骤 2: 把 calculateAmount 移到 src/domain/pricing.ts 步骤 3: 将所有调用方的 import 路径更新为新路径 步骤 4: 把 processOrder 重命名为 handleOrderSubmission - 每步提交前跑测试确认绿灯,再提交,再进行下一步。
- 若某步执行中发现需要同时改另一件事,先把当前步骤提交或暂存,再另起一个步骤。
4. 自动化优先,不手动批量改
规则: 能用 IDE 重构工具、代码迁移脚本(codemod)、语言服务器安全执行的重构,不要用手写替换或正则批量改;手改正则是大仓库重构引入 bug 的重灾区。
为什么: AI 遇到"把全仓库 500 处 getUserById 改名成 findUserById"时,最容易的做法是写个正则替换脚本或直接生成修改后的文件列表。问题是:正则不理解语法,会改到字符串字面量、注释、不同作用域下同名但含义不同的函数;手工批量替换会跳过动态调用(obj[methodName]())、装饰器、反射场景。IDE 的语言感知重命名会处理这些边界情况,而 AI 生成的正则脚本几乎不会。
怎么做:
- 重命名类/函数/变量:优先用 IDE 的"Rename Symbol"(VSCode F2、IntelliJ Shift+F6),它走语言服务器,能处理所有引用,包括动态调用和类型声明。
- 大规模迁移(如 API 升级、框架切换):优先找官方或社区提供的 codemod 工具(如
jscodeshift、ts-migrate),它们对语法树操作,比正则安全。 - 确实需要脚本替换时:先在小范围(单个文件)跑,人工核对输出正确后再扩大范围,绝不一次性盲跑全仓库。
- 批量改完后,用 Grep 抽查几个典型调用点,确认改动符合预期,没有误改。
5. 改前做影响面分析,大改先对齐团队
规则: 动手前用搜索工具把所有调用点、跨模块引用、对外接口全部找出来;影响面超出单个模块时,先把重构范围和计划同步给团队,拿到共识再动手。
为什么: AI 被要求重构一个函数时,只看得到当前文件,不会主动评估这个函数还被哪些模块依赖、是否有外部包导入、是否被测试 mock 住。常见翻车:把一个看起来"内部"的工具函数改了接口,没发现它被另一个子包直接引用,导致那个子包在 CI 里静默编译失败;或者移动了一个文件,没更新 barrel export,下游的 tree-shaking 路径断了,但不报错只是包变大了,很久后才发现。对于影响面大的重构,团队对齐还有另一个作用:避免和并行开发的同事产生大量合并冲突。
怎么做:
- 改动前用 Grep 搜索目标符号名,确认全部调用点的位置和数量。
- 检查是否有对外导出(barrel index 文件、package.json
exports字段、公共 API 文档),若有则影响面包含外部使用者。 - 画出依赖链:「修改 A → 影响 B、C 模块 → B 被 D 依赖 → 需同步检查 D」,遇到不确定的节点就继续往下追。
- 若影响超过 3 个模块或涉及对外接口,先在 PR 描述或设计文档里写清楚重构计划,让团队 review 计划再 review 代码。
正例 / 反例
反例:大爆炸式重构,一次改几十个文件,测试全红无法定位
# 反例 — AI 一次性"重构完成",单个 PR 包含:
# - 重命名了 12 个函数
# - 把 3 个文件合并成 1 个
# - 抽了 2 个新的抽象类
# - 顺手修了 2 个"看起来不对"的逻辑
# - 更新了所有 import 路径
git log --oneline
# a1b2c3d refactor: 重构 order 模块
# 跑测试结果:
# FAIL src/order/order.test.ts
# FAIL src/payment/payment.test.ts
# FAIL src/notification/notification.test.ts
# 7 个测试挂掉,但不知道哪一步改坏的
# git bisect 无从下手——只有一个提交
# 只能整体回滚,重构归零正例:单一变换、每步绿灯、可精确二分回退
# 正例 — 同样的重构目标,拆成独立的小步骤
git log --oneline
# f6e5d4c refactor: 把 calculateAmount 从 processOrder 中抽出为独立函数
# e3d2c1b refactor: 把 calculateAmount 移动到 src/domain/pricing.ts
# b9a8f7e refactor: 更新所有调用方 import 路径指向新位置
# 9c8b7a6 refactor: 把 processOrder 重命名为 handleOrderSubmission
# 每步提交前都跑过测试:
# 步骤 1 后 → 全绿 ✓
# 步骤 2 后 → 全绿 ✓
# 步骤 3 后 → 全绿 ✓
# 步骤 4 后 → 发现 2 个测试挂掉 ← 定位精确,只需检查重命名这一步
# git bisect 直接指向步骤 4,发现遗漏了一处动态调用:
# const handler = obj['processOrder']; ← 字符串没跟着改
# 修复一行,重新提交,全绿两者的本质差异:
| 维度 | 反例(大爆炸) | 正例(小步单一) |
| 单次提交改动量 | 几十个文件,多种变换混合 | 一种变换,改动可独立描述 |
| 测试挂掉时定位 | 无从下手,7 个测试挂掉不知原因 | 精确到某一步,范围可控 |
| 回退成本 | 整体回滚,重构归零 | 只回退出问题那一步,其余保留 |
| Code review 效率 | Reviewer 无法判断哪些是结构变动哪些是逻辑变动 | 每个 commit 目的单一,可快速审查 |
自查清单
- 重构前已有测试覆盖关键路径,或已补写特征测试锁住现有行为,跑过一遍确认全绿。
- 本次重构没有混入任何逻辑修改——若发现 bug,已另记为独立任务,没有在此处顺手修。
- 每个提交只包含一种重构操作(改名 / 抽函数 / 移文件),操作类型在提交信息中已明确说明。
- 重命名或移动前已用 Grep 找出全部调用点,没有遗漏的引用位置。
- 对批量改动(重命名、路径迁移)优先使用了 IDE 或 codemod 工具,而非手写正则脚本。
- 若影响面超过单个模块或涉及对外接口,已先同步团队并拿到共识,再开始动手。
- 每个重构步骤完成后都跑了测试,确认绿灯才继续下一步,没有攒步骤一起验证。
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

