06 - 重构优化食谱
安全地改善代码结构、类型安全与运行性能,每一步可验证、可回退。
适用场景
| 场景 | 信号 | 食谱 |
|---|---|---|
| 文件膨胀 | 单文件超过 300 行或包含 3+ 职责 | 食谱 1:模块拆分 |
| 类型薄弱 | 存在 any、缺少接口定义 | 食谱 2:类型增强 |
| 性能瓶颈 | 慢查询、大列表卡顿、bundle 过大 | 食谱 3:性能优化 |
| 代码异味 | 长函数、深嵌套、重复逻辑 | 食谱 4:代码异味消除 |
| 版本老旧 | 依赖落后 2+ 个大版本、有安全公告 | 食谱 5:依赖升级 |
| 遗留包袱 | 回调地狱、Class 组件、CommonJS | 食谱 6:遗留代码改造 |
食谱 1:模块拆分
场景描述
单个文件职责过多、行数膨胀,导致难以测试和复用。需要在不改变外部行为的前提下拆分为多个内聚模块。
核心模板
分析 {{目标文件}},按职责将其拆分为更小的模块。
要求:
1. 先列出当前文件中的所有职责(函数/类/常量分组)
2. 提出拆分方案:每个新模块的文件名、包含的导出项、单一职责描述
3. 保持原文件作为 barrel export(re-export),确保外部 import 不需要改动
4. 每拆出一个模块后立即运行 {{验证命令}} 确认不破坏现有功能
5. 最后清理原文件中的冗余代码
技术栈:{{技术栈}}
目标目录结构:{{期望结构}}变量说明
| 变量 | 含义 | 示例 |
|---|---|---|
{{目标文件}} | 需要拆分的文件路径 | src/services/user.service.ts |
{{验证命令}} | 每步后运行的验证命令 | npm test && npm run lint |
{{技术栈}} | 项目技术栈 | Next.js + TypeScript + Prisma |
{{期望结构}} | 拆分后的目录结构示意 | src/services/user/ 下按职责拆分 |
好坏对比
❌ 把 user.service.ts 拆小一点
✅ 分析 src/services/user.service.ts(当前 480 行),按职责拆分。先列出所有导出函数并分组,提出拆分方案(每模块 ≤ 150 行),原文件保留为 barrel export,每拆一个跑 npm test。
实战案例
分析 src/services/order.service.ts,按职责拆分。
当前问题:单文件包含订单创建、支付处理、库存扣减、通知发送,行数已达 500。
拆分目标:
- order-create.service.ts — 订单创建与校验
- order-payment.service.ts — 支付流程处理
- inventory.service.ts — 库存扣减与回滚
- notification.service.ts — 订单状态通知
- index.ts — barrel export,保持外部 import 兼容
约束:每个模块单一职责,不超过 150 行。共享类型放 types.ts。
每拆完一个模块跑 npm test,全绿再继续下一个。Claude 增强 💡
- 拆分前先运行
/impact order.service.ts了解引用图,避免遗漏上游调用者 - 使用
先列出拆分方案,不要写代码让 Claude 先输出计划,确认后再执行 - 每步拆分后让 Claude 运行测试,形成"拆分 → 验证 → 下一步"的小步循环
食谱 2:类型增强
场景描述
项目中存在大量 any 类型、缺少接口定义、类型断言滥用,导致编译器无法捕获错误。需要渐进式地补充和强化类型。
核心模板
对 {{目标范围}} 进行类型增强。
当前问题:{{类型问题描述}}
要求:
1. 搜索目标范围内所有 any / as any / @ts-ignore,列出清单
2. 按风险从低到高排序,优先处理工具函数和公共接口
3. 为每个 any 提供具体的类型替代方案
4. 不要用 unknown 简单替代 any——给出真正的业务类型
5. 如果需要新增类型定义,放到 {{类型目录}}
6. 每修复一批后运行 {{验证命令}} 确认类型检查通过
严格模式目标:{{TS 严格选项}}变量说明
| 变量 | 含义 | 示例 |
|---|---|---|
{{目标范围}} | 需要增强类型的目录或文件 | src/services/ |
{{类型问题描述}} | 当前类型问题概述 | 23 处 any,5 处 @ts-ignore |
{{类型目录}} | 类型定义存放目录 | src/types/ |
{{验证命令}} | 类型检查命令 | npx tsc --noEmit |
{{TS 严格选项}} | 要开启的 TS 严格选项 | strict: true, noUncheckedIndexedAccess: true |
好坏对比
❌ 把代码里的 any 都去掉
✅ 对 src/services/ 进行类型增强。当前 12 个文件存在 23 处 any 和 5 处 @ts-ignore。优先处理公共接口,新增类型放 src/types/,每修复 5 个后跑 npx tsc --noEmit。
实战案例
为 src/app/api/ 下所有路由处理函数添加严格类型。
当前状况:
- request body 多处用 any 接收
- response 没有统一的类型结构
- 参考 src/types/api.ts 中已有的 ApiResponse<T> 泛型
要求:
1. 搜索所有 route.ts 中的 any 和未类型化的 request body
2. 每个路由定义 RequestBody 和 ResponseData 类型
3. 用 zod schema 做运行时校验,并用 z.infer 推导类型
4. 返回值统一使用 ApiResponse<T> 包装
5. 每改完一个路由跑 npx tsc --noEmit && npm testClaude 增强 💡
- 让 Claude 先用 Grep 搜索
any和@ts-ignore生成全量清单,再逐批修复 - 对于第三方库类型,让 Claude 搜索
@types/包或查看库的类型导出 - 修复完成后运行
/review确认没有引入新的类型问题
食谱 3:性能优化
场景描述
应用出现可感知的性能问题:页面加载慢、接口响应慢、内存占用高。需要定位瓶颈并实施针对性优化,而非盲目优化。
核心模板
对 {{性能问题区域}} 进行性能优化。
问题现象:{{现象描述}}
已知数据:{{性能指标}}
要求:
1. 先分析可能的性能瓶颈点,列出假设清单
2. 针对每个假设,说明诊断方法和预期收益
3. 按预期收益从高到低排序,逐个实施
4. 每项优化前后给出可量化的对比方案
5. 不要做"看起来更快"的微优化——只做有数据支撑的优化
技术栈:{{技术栈}}
性能目标:{{量化目标}}变量说明
| 变量 | 含义 | 示例 |
|---|---|---|
{{性能问题区域}} | 出现性能问题的模块 | 订单列表页 |
{{现象描述}} | 可感知的性能问题 | 列表滚动卡顿,加载 3s+ |
{{性能指标}} | 已采集的数据 | LCP 4.2s, API P95 1.8s |
{{技术栈}} | 项目技术栈 | React + TanStack Query + Prisma |
{{量化目标}} | 优化后的目标指标 | LCP < 2s, API P95 < 500ms |
好坏对比
❌ 页面太慢了,优化一下
✅ 优化订单列表页加载性能。LCP 4.2s,API P95 1.8s,列表 500 条无分页无虚拟滚动。分析瓶颈是 API 还是渲染,逐项优化,每项可独立验证。目标 LCP < 2s。
实战案例
优化 src/services/report.service.ts 中的 generateReport 函数性能。
现象:/api/reports 接口 P95 响应时间 3.5s
当前实现:
- 4 次串行数据库查询(用户、订单、支付、库存)
- 查询结果在 JS 层做关联和聚合
- 无缓存,每次请求都全量计算
优化方向(按优先级):
1. 将串行查询改为 Promise.all 并行查询
2. 数据库层面用 JOIN 替代 JS 层关联
3. 对不常变动的维度数据加 Redis 缓存
4. 为高频查询字段添加索引
每项优化后对比响应时间,目标 P95 < 800ms。Claude 增强 💡
- 让 Claude 先分析代码结构再提方案,避免"优化了不是瓶颈的地方"
- 数据库优化时让 Claude 用
EXPLAIN ANALYZE分析查询计划 - 每项优化后运行测试确保功能不变:
优化后跑 npm test,全绿再继续
Profiling 驱动诊断(性能优化黄金法则)
不要猜测瓶颈,用数据定位。 优化的第一步永远是测量,不是改代码。
诊断工具箱(按层级):
后端 API → curl -w "%{time_total}s" 测端到端 → 数据库 EXPLAIN ANALYZE
前端渲染 → Chrome DevTools Performance 面板 → React Profiler
Bundle → npx next build --profile → webpack-bundle-analyzer
诊断→优化循环:
1. 测量当前指标(建立基线)
2. 定位瓶颈(profiling 数据,不是直觉)
3. 只优化瓶颈(最高收益优先)
4. 重新测量(量化效果)
5. 不够则继续,够了就停食谱 4:代码异味消除
场景描述
代码可运行但存在结构性问题:过长函数、深层嵌套、重复逻辑、参数过多。这些异味降低可维护性,需要在不改变行为的前提下重构。
核心模板
检查 {{目标范围}} 中的代码异味并重构。
重点关注以下异味类型:
{{异味清单}}
要求:
1. 扫描目标范围,列出所有发现的异味及其位置
2. 按严重程度排序(影响可维护性 > 影响可读性 > 风格问题)
3. 对每个异味给出重构方案和预期效果
4. 逐个修复,每次修复后运行 {{验证命令}}
5. 重构只改结构,不改行为——测试结果必须不变
参考规范:{{编码规范}}变量说明
| 变量 | 含义 | 示例 |
|---|---|---|
{{目标范围}} | 要检查的目录或文件 | src/services/ |
{{异味清单}} | 重点关注的异味类型 | 长函数、深嵌套、重复代码、God Class |
{{验证命令}} | 每步后的验证命令 | npm test && npm run lint |
{{编码规范}} | 项目编码规范参考 | CLAUDE.md 中的编码规范 |
好坏对比
❌ 这段代码写得不好,重构一下
✅ 检查 src/services/payment.service.ts 的代码异味。重点:长函数(>40行)提取子函数、深嵌套(>3层)改早返回、重复逻辑提取工具函数、魔法数字提取常量。逐个修复,每次跑 npm test。
实战案例
重构 src/handlers/webhook.handler.ts 中的 handleEvent 函数。
当前问题:
- 函数体 120 行,包含 5 层嵌套的 if-else
- switch 分支中混合了校验、业务逻辑、数据库操作
- 错误处理散布在各层级,无统一模式
重构目标:
1. 用早返回消除深层嵌套
2. 每个 case 分支提取为独立的处理函数
3. 校验逻辑集中到入口,用 guard clause 模式
4. 统一错误处理:所有异常统一抛 AppError,外层 catch 兜底
每步改完跑 npm test,确保 webhook 集成测试全部通过。Claude 增强 💡
- 让 Claude 先用静态分析视角列出异味清单,再逐个讨论修复方案
- 使用
/review在重构完成后做全量审查,确认没有引入新问题 - 大范围重构分文件分批进行,避免一个 PR 改动过大
食谱 5:依赖升级
场景描述
项目依赖落后多个版本,存在安全漏洞或兼容性问题。大版本升级涉及 breaking changes,需要系统性规划,而非直接 npm update。
核心模板
将 {{依赖名}} 从 {{当前版本}} 升级到 {{目标版本}}。
升级原因:{{升级动机}}
要求:
1. 查阅 {{依赖名}} 的 CHANGELOG / Migration Guide,列出所有 breaking changes
2. 搜索项目中所有使用了 breaking API 的位置
3. 制定分步迁移计划,每步可独立验证
4. 先在一个分支上执行升级,跑全量测试
5. 列出升级后需要调整的配置文件
6. 如果有 peer dependency 冲突,一并处理
技术栈:{{技术栈}}
测试命令:{{测试命令}}变量说明
| 变量 | 含义 | 示例 |
|---|---|---|
{{依赖名}} | 要升级的依赖包名 | next |
{{当前版本}} | 当前版本号 | 13.4.x |
{{目标版本}} | 目标版本号 | 14.x |
{{升级动机}} | 为什么要升级 | 安全漏洞 CVE-xxx / 新特性需要 |
{{技术栈}} | 项目技术栈 | Next.js + React 18 + Prisma |
{{测试命令}} | 全量测试命令 | npm test && npm run build && npm run e2e |
好坏对比
❌ 帮我升级 Next.js 到最新版
✅ 将 Next.js 从 13.4.19 升级到 14.1.0。原因:需要 Server Actions 稳定版。先查 Migration Guide 列出 breaking changes,搜索受影响用法,分步执行,跑 npm test && npm run build。
实战案例
将 Prisma 从 4.x 升级到 5.x。
升级原因:Prisma 4 将停止安全更新,且需要 JSON 字段类型过滤新特性。
分步计划:
1. 阅读 Prisma 5 升级指南,列出 breaking changes
2. 搜索受影响用法(findUnique 行为变化、原始查询 API、中间件 API)
3. 升级步骤:
a. 升级 @prisma/client 和 prisma 到 5.x
b. 运行 npx prisma generate 重新生成客户端
c. 修复编译错误并跑全量测试
d. 验证数据库迁移兼容性
测试命令:npx prisma generate && npm test && npm run buildClaude 增强 💡
- 升级前运行
/impact {{依赖名}}分析哪些模块用了该依赖 - 让 Claude 搜索该依赖的 GitHub Release Notes 或 Migration Guide
- 建议在独立分支上操作:
先建 feat/upgrade-xxx 分支,升级完再合并 - 升级完成后运行
/review审查所有改动
食谱 6:遗留代码改造
场景描述
项目中存在老旧代码模式:回调地狱、Class 组件、var 声明、CommonJS require 等。需要渐进式改造为现代写法,同时保持功能不变。
核心模板
将 {{目标范围}} 中的遗留代码模式改造为现代写法。
当前遗留模式:
{{遗留模式清单}}
目标现代模式:
{{现代模式清单}}
要求:
1. 扫描目标范围,列出所有遗留模式的位置和数量
2. 按改造风险从低到高排序
3. 每次只改造一种模式,改完跑 {{验证命令}}
4. 保持接口不变——函数签名、导出名、外部行为都不能变
5. 如果某处改造风险过高,标注跳过并说明原因
技术栈:{{技术栈}}变量说明
| 变量 | 含义 | 示例 |
|---|---|---|
{{目标范围}} | 要改造的目录或文件 | src/legacy/ |
{{遗留模式清单}} | 当前存在的老旧模式 | callback, var, require, prototype |
{{现代模式清单}} | 改造后的目标模式 | async/await, const/let, ES Module import |
{{验证命令}} | 验证命令 | npm test && npm run build |
{{技术栈}} | 当前技术栈 | Node.js 20 + TypeScript 5 |
好坏对比
❌ 这些代码太老了,帮我现代化
✅ 将 src/utils/ 中的遗留模式改造为现代写法。12 处 callback→async/await,8 处 var→const,5 处 require→import。按风险排序,var 最安全先做,回调最后做。每改完一种跑 npm test。
实战案例
将 src/components/Dashboard/ 下的 Class 组件改造为函数组件 + Hooks。
待改造清单:
- DashboardPage.tsx — componentDidMount, setState
- StatsPanel.tsx — shouldComponentUpdate
- UserTable.tsx — ref, lifecycle methods
改造映射:
- componentDidMount → useEffect
- setState → useState
- shouldComponentUpdate → React.memo
- createRef → useRef
- HOC 模式 → 自定义 Hook
逐个组件改造,每改完一个跑 npm test 并确认 props 接口未变。Claude 增强 💡
- 改造前运行
/impact {{目标文件}}确认不会影响其他模块 - 让 Claude 搜索项目中同类现代写法作为改造参考
- 大量文件的批量改造分批进行,每批后运行
/review确认质量
组合技巧
安全重构三步曲
我要对 {{目标模块}} 进行重构。请按以下三步执行:
第一步——影响分析:
搜索所有引用 {{目标模块}} 的文件,列出影响范围和现有测试覆盖。
第二步——补充测试:
对测试覆盖不足的地方,先补充测试用例,确保重构前行为有保障。
第三步——执行重构:
在测试全部通过的基础上开始重构,每改一步跑一次测试。渐进式大规模改造
项目需要进行以下改造(按优先级排序):
1. {{改造项1}} — 影响范围:{{范围1}}
2. {{改造项2}} — 影响范围:{{范围2}}
3. {{改造项3}} — 影响范围:{{范围3}}
执行原则:
- 每个改造项独立 PR,不混合
- 每个 PR 改动不超过 10 个文件
- 先做影响范围最小的,积累信心后再做大的
- 每个 PR 通过 CI + Code Review 后再做下一个重构 + 类型 + 测试联动
对 {{目标文件}} 进行三合一改造:
1. 类型增强:消除 any,定义严格类型
2. 结构重构:拆分长函数,消除代码异味
3. 测试补全:为重构后的每个函数补充单元测试
执行顺序:先加类型(编译器保护)→ 再重构(有类型兜底)→ 最后补测试(锁定行为)。
每步都跑 npx tsc --noEmit && npm test。相关资源
- doc-15 Prompt 工程实战 — 提示词理论框架与速查表
- doc-12 效率最佳实践 — 锚定文件、小步快跑等工程模式
- /review Skill — 重构后代码审查
- /impact Skill — 重构前影响分析
- 05-调试排错食谱 — 重构中发现 bug 时的排错流程
- 07-文档写作食谱 — 重构后更新文档