Skip to content

06 - 重构优化食谱

安全地改善代码结构、类型安全与运行性能,每一步可验证、可回退。

适用场景

场景信号食谱
文件膨胀单文件超过 300 行或包含 3+ 职责食谱 1:模块拆分
类型薄弱存在 any、缺少接口定义食谱 2:类型增强
性能瓶颈慢查询、大列表卡顿、bundle 过大食谱 3:性能优化
代码异味长函数、深嵌套、重复逻辑食谱 4:代码异味消除
版本老旧依赖落后 2+ 个大版本、有安全公告食谱 5:依赖升级
遗留包袱回调地狱、Class 组件、CommonJS食谱 6:遗留代码改造

食谱 1:模块拆分

场景描述

单个文件职责过多、行数膨胀,导致难以测试和复用。需要在不改变外部行为的前提下拆分为多个内聚模块。

核心模板

text
分析 {{目标文件}},按职责将其拆分为更小的模块。

要求:
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。

实战案例

text
分析 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 类型、缺少接口定义、类型断言滥用,导致编译器无法捕获错误。需要渐进式地补充和强化类型。

核心模板

text
对 {{目标范围}} 进行类型增强。

当前问题:{{类型问题描述}}

要求:
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。

实战案例

text
为 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 test

Claude 增强 💡

  • 让 Claude 先用 Grep 搜索 any@ts-ignore 生成全量清单,再逐批修复
  • 对于第三方库类型,让 Claude 搜索 @types/ 包或查看库的类型导出
  • 修复完成后运行 /review 确认没有引入新的类型问题

食谱 3:性能优化

场景描述

应用出现可感知的性能问题:页面加载慢、接口响应慢、内存占用高。需要定位瓶颈并实施针对性优化,而非盲目优化。

核心模板

text
对 {{性能问题区域}} 进行性能优化。

问题现象:{{现象描述}}
已知数据:{{性能指标}}

要求:
1. 先分析可能的性能瓶颈点,列出假设清单
2. 针对每个假设,说明诊断方法和预期收益
3. 按预期收益从高到低排序,逐个实施
4. 每项优化前后给出可量化的对比方案
5. 不要做"看起来更快"的微优化——只做有数据支撑的优化

技术栈:{{技术栈}}
性能目标:{{量化目标}}

变量说明

变量含义示例
&#123;&#123;性能问题区域&#125;&#125;出现性能问题的模块订单列表页
&#123;&#123;现象描述&#125;&#125;可感知的性能问题列表滚动卡顿,加载 3s+
&#123;&#123;性能指标&#125;&#125;已采集的数据LCP 4.2s, API P95 1.8s
&#123;&#123;技术栈&#125;&#125;项目技术栈React + TanStack Query + Prisma
&#123;&#123;量化目标&#125;&#125;优化后的目标指标LCP < 2s, API P95 < 500ms

好坏对比

页面太慢了,优化一下

优化订单列表页加载性能。LCP 4.2s,API P95 1.8s,列表 500 条无分页无虚拟滚动。分析瓶颈是 API 还是渲染,逐项优化,每项可独立验证。目标 LCP < 2s。

实战案例

text
优化 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 驱动诊断(性能优化黄金法则)

不要猜测瓶颈,用数据定位。 优化的第一步永远是测量,不是改代码。

text
诊断工具箱(按层级):
  后端 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:代码异味消除

场景描述

代码可运行但存在结构性问题:过长函数、深层嵌套、重复逻辑、参数过多。这些异味降低可维护性,需要在不改变行为的前提下重构。

核心模板

text
检查 {{目标范围}} 中的代码异味并重构。

重点关注以下异味类型:
{{异味清单}}

要求:
1. 扫描目标范围,列出所有发现的异味及其位置
2. 按严重程度排序(影响可维护性 > 影响可读性 > 风格问题)
3. 对每个异味给出重构方案和预期效果
4. 逐个修复,每次修复后运行 {{验证命令}}
5. 重构只改结构,不改行为——测试结果必须不变

参考规范:{{编码规范}}

变量说明

变量含义示例
&#123;&#123;目标范围&#125;&#125;要检查的目录或文件src/services/
&#123;&#123;异味清单&#125;&#125;重点关注的异味类型长函数、深嵌套、重复代码、God Class
&#123;&#123;验证命令&#125;&#125;每步后的验证命令npm test && npm run lint
&#123;&#123;编码规范&#125;&#125;项目编码规范参考CLAUDE.md 中的编码规范

好坏对比

这段代码写得不好,重构一下

检查 src/services/payment.service.ts 的代码异味。重点:长函数(>40行)提取子函数、深嵌套(>3层)改早返回、重复逻辑提取工具函数、魔法数字提取常量。逐个修复,每次跑 npm test。

实战案例

text
重构 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

核心模板

text
将 {{依赖名}} 从 {{当前版本}} 升级到 {{目标版本}}。

升级原因:{{升级动机}}

要求:
1. 查阅 {{依赖名}} 的 CHANGELOG / Migration Guide,列出所有 breaking changes
2. 搜索项目中所有使用了 breaking API 的位置
3. 制定分步迁移计划,每步可独立验证
4. 先在一个分支上执行升级,跑全量测试
5. 列出升级后需要调整的配置文件
6. 如果有 peer dependency 冲突,一并处理

技术栈:{{技术栈}}
测试命令:{{测试命令}}

变量说明

变量含义示例
&#123;&#123;依赖名&#125;&#125;要升级的依赖包名next
&#123;&#123;当前版本&#125;&#125;当前版本号13.4.x
&#123;&#123;目标版本&#125;&#125;目标版本号14.x
&#123;&#123;升级动机&#125;&#125;为什么要升级安全漏洞 CVE-xxx / 新特性需要
&#123;&#123;技术栈&#125;&#125;项目技术栈Next.js + React 18 + Prisma
&#123;&#123;测试命令&#125;&#125;全量测试命令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。

实战案例

text
将 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 build

Claude 增强 💡

  • 升级前运行 /impact &#123;&#123;依赖名&#125;&#125; 分析哪些模块用了该依赖
  • 让 Claude 搜索该依赖的 GitHub Release Notes 或 Migration Guide
  • 建议在独立分支上操作:先建 feat/upgrade-xxx 分支,升级完再合并
  • 升级完成后运行 /review 审查所有改动

食谱 6:遗留代码改造

场景描述

项目中存在老旧代码模式:回调地狱、Class 组件、var 声明、CommonJS require 等。需要渐进式改造为现代写法,同时保持功能不变。

核心模板

text
将 {{目标范围}} 中的遗留代码模式改造为现代写法。

当前遗留模式:
{{遗留模式清单}}

目标现代模式:
{{现代模式清单}}

要求:
1. 扫描目标范围,列出所有遗留模式的位置和数量
2. 按改造风险从低到高排序
3. 每次只改造一种模式,改完跑 {{验证命令}}
4. 保持接口不变——函数签名、导出名、外部行为都不能变
5. 如果某处改造风险过高,标注跳过并说明原因

技术栈:{{技术栈}}

变量说明

变量含义示例
&#123;&#123;目标范围&#125;&#125;要改造的目录或文件src/legacy/
&#123;&#123;遗留模式清单&#125;&#125;当前存在的老旧模式callback, var, require, prototype
&#123;&#123;现代模式清单&#125;&#125;改造后的目标模式async/await, const/let, ES Module import
&#123;&#123;验证命令&#125;&#125;验证命令npm test && npm run build
&#123;&#123;技术栈&#125;&#125;当前技术栈Node.js 20 + TypeScript 5

好坏对比

这些代码太老了,帮我现代化

将 src/utils/ 中的遗留模式改造为现代写法。12 处 callback→async/await,8 处 var→const,5 处 require→import。按风险排序,var 最安全先做,回调最后做。每改完一种跑 npm test。

实战案例

text
将 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 &#123;&#123;目标文件&#125;&#125; 确认不会影响其他模块
  • 让 Claude 搜索项目中同类现代写法作为改造参考
  • 大量文件的批量改造分批进行,每批后运行 /review 确认质量

组合技巧

安全重构三步曲

text
我要对 {{目标模块}} 进行重构。请按以下三步执行:

第一步——影响分析:
搜索所有引用 {{目标模块}} 的文件,列出影响范围和现有测试覆盖。

第二步——补充测试:
对测试覆盖不足的地方,先补充测试用例,确保重构前行为有保障。

第三步——执行重构:
在测试全部通过的基础上开始重构,每改一步跑一次测试。

渐进式大规模改造

text
项目需要进行以下改造(按优先级排序):
1. {{改造项1}} — 影响范围:{{范围1}}
2. {{改造项2}} — 影响范围:{{范围2}}
3. {{改造项3}} — 影响范围:{{范围3}}

执行原则:
- 每个改造项独立 PR,不混合
- 每个 PR 改动不超过 10 个文件
- 先做影响范围最小的,积累信心后再做大的
- 每个 PR 通过 CI + Code Review 后再做下一个

重构 + 类型 + 测试联动

text
对 {{目标文件}} 进行三合一改造:
1. 类型增强:消除 any,定义严格类型
2. 结构重构:拆分长函数,消除代码异味
3. 测试补全:为重构后的每个函数补充单元测试

执行顺序:先加类型(编译器保护)→ 再重构(有类型兜底)→ 最后补测试(锁定行为)。
每步都跑 npx tsc --noEmit && npm test。

相关资源

面向个人开发者的 AI 辅助编程工程化方案