第24期 | AI辅助调试与代码审查
第24期 | AI辅助调试与代码审查
🎯 今天你将学会
- 用 AI 定位 Bug 的系统性方法(不只是「帮我看看哪里错了」)
- 用 AI 做 Code Review 的完整流程
- 用 AI 分析性能瓶颈和潜在隐患
- 建立一个「AI 调试 Prompt 工具箱」
📖 核心知识
调试的三个层次:你在哪一层
很多前端开发者遇到 Bug 的第一反应是:打开 DevTools,看 Console,然后盯着报错信息发呆。这是Level 1——看表象。
| 层次 | 行为 | 效率 | AI 能帮什么 |
|---|---|---|---|
| L1 看表象 | 读报错信息、猜测原因 | 低,靠经验直觉 | AI 解读报错、给出可能原因 |
| L2 追链路 | 从报错位置追踪到根因 | 中,需要理解代码流程 | AI 分析调用链、追踪状态变化 |
| L3 防隐患 | 还没报错就发现潜在问题 | 高,预防性 | AI 审查代码、发现边界情况 |
AI 在每个层次都能帮你——但用法不同。L1 给报错信息,L2 给相关代码上下文,L3 给整段逻辑让 AI 审查。
用 AI 定位 Bug:系统方法
STEP 1:收集信息
在给 AI 之前,你先收集:
- 完整的报错信息(不是截取一部分)
- 出错时的输入数据
- 预期行为 vs 实际行为
STEP 2:构建 CRISP 调试 Prompt
[Context] @{出错的文件} + @{相关文件} [Role] 前端调试专家 [Instruction] 定位并修复以下 Bug [Specification] - 错误现象:{实际行为} - 预期行为:{应该怎样} - 错误信息:{完整报错} - 触发条件:{在什么操作下出错} - 已排除:{你已经确认不是问题的方向} [Proof] 修复后正常工作,写出验证步骤STEP 3:让 AI 先分析根因,再给修复方案
关键:不要让 AI 直接改代码。让它先分析,你确认分析对了,再让它修。
第一步:分析这个 Bug 的根因,列出所有可能的原因(按可能性排序) 第二步:等我确认后,再给出修复方案为什么要先分析再修复?因为 AI 有时会「修 A 却说修了 B」——它改了代码但分析原因说错了。你先确认分析,就能确保修复方向是对的。
常见 Bug 类型及 AI 定位策略
| Bug 类型 | 特征 | AI 定位策略 |
|---|---|---|
| 类型错误 | TypeError: Cannot read property 'x' of undefined | 引用相关文件 + 类型定义,让 AI 找到数据流断点 |
| 异步时序 | 数据还没返回就渲染 | 引用 fetch/async 代码 + 组件渲染逻辑,让 AI 分析 Promise 链 |
| 状态不更新 | 点击/输入后 UI 没变化 | 引用 store/setState + 事件处理器,让 AI 检查 state 是否正确触发 |
| 样式冲突 | CSS 不生效/覆盖 | 引用组件 CSS + 全局样式,让 AI 分析 specificity 和层叠顺序 |
| 渲染循环 | 页面卡死/无限更新 | 引用 useEffect + state 依赖,让 AI 检查依赖数组是否完整 |
实战示例:定位一个「列表不刷新」Bug
报错信息:没有报错,但现象是「上传新文件后列表没更新」
[Context] @src/features/ipa/store.ts @src/features/ipa/components/IPAList.tsx @src/features/ipa/services/upload.ts [Role] 前端调试专家 [Instruction] 定位以下 Bug:上传 IPA 文件后,列表没有自动刷新 [Specification] - 错误现象:上传成功后列表仍然是旧数据,手动刷新页面后才更新 - 预期行为:上传成功后列表自动更新,显示新上传的文件 - 已排除:上传接口本身是正常的(后端返回了新数据) [Proof] 修复后上传成功列表自动更新AI 分析:
可能原因(按可能性排序): 1. 【高概率】上传成功后没有重新调用 fetchIPAList - 分析:upload.ts 的 onSuccess 回调没有触发 store 的刷新 action 2. 【中概率】fetchIPAList 返回了新数据但组件没有重新渲染 - 分析:组件可能用了 stale 数据,或者 selector 没正确订阅 3. 【低概率】缓存问题 - 分析:如果用了 React Query 或 SWR,可能是缓存策略导致 建议先检查第1个原因:在 upload service 的 onSuccess 中是否调用了 store.fetchIPAList()根因确认:第1个原因是对的——upload.ts 的onSuccess只显示了一个 toast 提示,没有调用store.fetchIPAList()。
修复方案:在 upload service 的 onSuccess 回调中加上ipaStore.fetchIPAList()。
用 AI 做 Code Review
AI Code Review 不是让 AI 替你审查整段代码——那样太泛了。好的 AI Review 是按维度审查,每个维度单独输出。
多维度审查 Prompt:
@{要审查的文件} 请从以下6个维度逐一审查这段代码,每个维度给出: - 问题列表(无问题则写"✅ 无问题") - 严重程度:🔴 高 / 🟡 中 / 🟢 低 - 建议修复方案 维度1:类型安全(TypeScript 类型是否完整、any 是否滥用) 维度2:性能(是否有不必要的重渲染、内存泄漏风险) 维度3:可维护性(代码是否清晰、命名是否规范、耦合度) 维度4:边界情况(空值、undefined、异常输入的处理) 维度5:可访问性(ARIA 属性、键盘操作、语义化标签) 维度6:安全(XSS 风险、数据验证、敏感信息暴露)审查输出示例:
维度1:类型安全 - 🔴 [高] API 响应类型用了 any,应定义 Response<T> 类型 → 建议:从 Swagger/API 文档生成类型定义 - 🟡 [中] Props 类型缺少可选标记,有些 prop 不必必传 → 建议:review Props 定义,合理标记 optional 维度2:性能 - 🟡 [中] useMemo 缺少依赖项,可能导致 stale 计算 → 建议:补齐依赖数组,或使用 useCallback 包裹引用 - 🟢 [低] 列表渲染缺少 key 优化,大数据量时可能慢 → 建议:确保 key 用唯一 id 而不是 index 维度3:可维护性 - ✅ 无问题 维度4:边界情况 - 🔴 [高] 搜索输入没有处理空字符串,可能导致 API 报错 → 建议:搜索为空时跳过 API 调用,直接显示全部数据 维度5:可访问性 - 🟡 [中] 按钮缺少 aria-label,屏幕阅读器无法理解 → 建议:给图标按钮添加 aria-label 描述 维度6:安全 - 🟢 [低] 使用了 dangerouslySetInnerHTML,但内容来自可信来源 → 建议:即便内容可信,也建议用 DOMPurify 做 sanitize用 AI 分析性能瓶颈
性能分析 Prompt:
@{要分析的组件/页面} 分析以下性能问题: 1. 列出所有可能导致性能问题的代码(重渲染、大计算、DOM 操作过多) 2. 对每个问题给出: - 影响程度:在什么数据量下会变慢 - 修复方案:优先级排序 3. 给出整体优化策略:哪些值得现在做,哪些可以等数据量大了再做 参考数据:当前数据量约 {N} 条,预计未来可能增长到 {M} 条常见误区
误区1:把报错截图直接丢给 AI
截图里的报错信息 AI 可能读不全或读错。复制文本,不要截图。
误区2:只给 AI 报错的那一个文件
Bug 的根因往往不在报错文件——可能在数据来源、状态管理、异步处理。给 AI 相关文件的上下文。
误区3:AI 说改什么就改什么
先确认 AI 的分析是对的,再改代码。有时候 AI 的「修复」只是掩盖了症状,根因还在。
🤖 AI协作实战
实战:找出 3 个隐藏 Bug
下面这段代码里我故意埋了 3 个 Bug,用 AI 找出来:
// UserList.tsximport{useEffect,useState}from'react';import{fetchUsers}from'../services/user';interfaceUser{id:number;name:string;email:string;role:string;}exportfunctionUserList(){const[users,setUsers]=useState<User[]>([]);const[search,setSearch]=useState('');const[loading,setLoading]=useState(false);useEffect(()=>{setLoading(true);fetchUsers().then(data=>{setUsers(data);setLoading(false);});},[search]);// Bug 1: search 变化触发 fetch,但 search 应该是本地过滤而非重新请求constfilteredUsers=users.filter(u=>u.name.includes(search)// Bug 2: 没有 toLowerCase,大小写敏感匹配);return(<div><input value={search}onChange={e=>setSearch(e.target.value)}/>{loading&&<p>加载中...</p>}<ul>{filteredUsers.map((u,i)=>(<li key={i}>{/* Bug 3: 用 index 作为 key,用户排序会出问题 */}{u.name}-{u.email}</li>))}</ul></div>);}我给 AI 的 Prompt:
@UserList.tsx 请从类型安全、性能、边界情况、可维护性四个维度审查这段代码。 对每个发现的问题标注严重程度(🔴高/🟡中/🟢低)并给出修复方案。AI 审查结果:
🔴 [高] useEffect 依赖数组包含 search,但 search 应该只做本地过滤 → 修复:移除 search 依赖,只在初始化时 fetchUsers() → 如果需要搜索触发 API,应单独处理搜索请求 🟡 [中] filter 用 includes 没有大小写不敏感匹配 → 修复:改为 u.name.toLowerCase().includes(search.toLowerCase()) 🟡 [中] 用 index 作为 key → 修复:改为 key={u.id},因为 User 有 id 字段 🟡 [中] fetchUsers 没有 error 处理 → 修复:加 .catch() 和 error state 🟢 [低] setLoading(false) 在 .then 中,如果请求失败 loading 状态不会重置 → 修复:在 .catch 中也 setLoading(false)AI 找到了我埋的 3 个 Bug,还额外发现了 2 个我没刻意埋但确实存在的问题(错误处理缺失)。这就是 AI Review 的价值——不只找你已知的问题,还能发现你没注意到的隐患。
学到了什么:让 AI 按维度审查比让它「随便看看」更有效。维度审查强制 AI 系统性思考,而不是凭直觉挑几个明显问题。
💻 动手练习
练习1(简单):用 CRISP 调试模板定位一个你项目中的真实 Bug
找一个你项目中存在的小 Bug(或者刚修过的一个 Bug),用 CRISP 调试模板写 Prompt,对比 AI 分析和你的原始定位过程,看哪个更快。
练习2(中等):对你的一个组件做 AI Code Review
选你项目中最复杂的一个组件,用本期提供的多维度审查 Prompt 做 Review。记录 AI 发现的问题中,有多少是你之前没注意到的。
练习3(挑战):故意埋 Bug 再找 Bug
写一个 50-100 行的 React 组件,故意埋 5 个 Bug(至少 1 个性能问题、1 个类型问题、1 个边界情况)。让 AI 审查,看它能找到几个。评估 AI 没找到的 Bug 的特征——是太隐蔽还是 AI 的审查维度不够?
📌 本期要点
- 调试三层:L1(看表象)→ L2(追链路)→ L3(防隐患),AI 在每层都能帮你但用法不同
- 先分析再修复:让 AI 先给根因分析,你确认后再修复——避免「修了症状没修根因」
- 多维度审查:按类型安全/性能/可维护性/边界情况/可访问性/安全六个维度,比「随便看看」系统得多
- 给够上下文:Bug 的根因往往不在报错文件,引用相关的数据流文件才能让 AI 精准定位
- 复制文本不要截图:报错信息用文本形式给 AI,不要截图——AI 读文本更准确
🔗 下期预告
下一期我们看设计稿→代码的快速通道——v0、Figma AI、截图转代码。你将学会用 AI 从设计稿生成可用的 React 组件,以及如何审查和修改 AI 生成的 UI 代码。
如果你没有苹果电脑,需要上传ios到APPStore可以访问以下网站
iPA上传工具 - IPA解析与AppStore提交
