高级调试提示词
全面系统审查(代码库审计)
- _“1. 将 API 调用从组件中分离: The _
ProjectListcomponent is directly fetching data. Suggestion: move data fetching to a dedicated hook or context to keep components pure UI.
- 将 API 调用从组件中分离:
ProjectList组件正在直接发起数据请求。建议:将数据获取逻辑移动到专用的 hook 或 context 中,以保持组件只负责展示 UI。 - 降低 Task 逻辑的耦合度: 任务完成状态的切换既在更新 state,又在直接写入 localStorage。应当重构为只有一个单一的数据源。
- 整理工具函数:
App.tsx中有一些工具函数,更适合放在一个utils文件夹中(例如日期格式化函数)。 - …”*
让你的提示词更具体、更有细节
针对易出问题更新的安全做法
性能优化检查
- “Data fetching:
ProjectList组件在每次渲染时都会获取数据。可以通过使用缓存,或将数据获取逻辑提到更高层级的上下文中来优化,这样就不会出现不必要的重复请求。考虑使用 state 或 context 在数据获取后存储项目数据。 - Re-renders:
TaskItem组件没有进行 memo 化,只要任意父级 state 发生变化,它就会重新渲染。如果任务很多,这会让交互变慢。建议:对TaskItem使用React.memo,以避免不必要的重复渲染。 - Assets: 注意到有一个 2MB 的图像(logo)。这相当大;可以压缩或使用更低分辨率的图像来加快加载速度。
- Bundle size: 所有页面都被打包在同一个 bundle 中。可以考虑进行代码分割(对大型模块使用动态
import()),以加快初始加载。 - …”*
处理持续存在的错误
- 先问问 AI 已经尝试过什么。 有时候在多次点击 Try to Fix 或手动输入提示之后,就不清楚到底改了什么。可以问:_“到目前为止,我们为这个错误尝试了哪些解决方案?”_。AI 会列出尝试过的方法,帮助你避免重复同样的修复。
- 让 AI 用简单的方式解释这个错误。 “请用简单的方式解释一下这个错误为什么会发生。” 这样可以看出 AI(以及你)是否真的理解它,你也有可能在这里发现某个误解。
- 考虑换一种思路。 问:_“鉴于这个错误一直在发生,我们是否可以尝试用不同的方法来实现目标?”_。AI 可能会提出一种不同的实现策略,从而绕开这个有问题的区域。
- 回滚并重来。 在最糟糕的情况下,你可能需要回退几个步骤。Lovable 允许你恢复到旧版本,甚至可以编辑过去的消息并回滚,以采用不同的思路。然后用更小的改动逐步推进。
调试流程示例
“卡在错误循环中”
在整个过程中,你都先把错误描述清楚,并让 AI 确认它的理解,而不是盲目地一遍遍点击 Try to Fix。
「功能没按预期工作」
本质上,通过描述你期望发生的事情(收到一封邮件)和实际发生的情况(什么都没发生,再加上一段日志),AI 就能够引导你完成整个排查过程。
“UI 元素消失了。”
AI 可能会检查组件是否仍然在被渲染,或者是否缺少 return 语句。
或许它发现重构时把父级 JSX 里的
ProjectList 删掉了。它会建议重新导入并把它加回去。或者,父级中的 state 变化导致这个列表现在被无意中过滤掉了。使用 DevTools 和控制台日志
根本原因分析、回滚与渐进增强
根本原因 vs. 症状
我看到你通过添加检查修复了空指针错误,但它一开始为什么会是 null 呢?我们能不能从根源上解决?
明智地回滚:
我把项目回滚到了添加通知功能之前。我们再实现一次,这次更仔细一些。
渐进增强:
- 添加失败的测试用例。
- 隔离问题并分析依赖关系。
- 在应用修复前先记录调查结果。
边做边记录:
Summarize what the issue was and how we fixed it.
README 或日志中。这样未来的你,或者项目中的其他任何人,都能更容易理解当时发生了什么以及你们是如何解决问题的。
知道什么时候该寻求人类帮助:
社区调试指南
错误修复
错误修复
在修复错误时,只专注于相关的代码部分,不要修改其他运行正常的部分。先分析报错信息并追踪到其根源。实施有针对性的修复,在解决具体问题的同时,确保与现有代码库保持兼容。在确认任何解决方案之前,一定要验证它既能解决最初的问题,又不会引入新的缺陷。始终保留已有的正常功能,避免重写与该错误没有直接关系的代码。
代码修改方案
代码修改方案
在修改现有代码时,应采用“外科手术式”的方式,只变更为实现所请求功能或修复所必需的部分。保留代码库中已有的变量命名、编码模式和架构决策。在提出修改建议前,先分析依赖关系,确保变更不会破坏现有功能。以最小差异(diff)的形式呈现改动,而不是完全重写代码。如果发现超出当前任务范围的改进点,请单独提出改进建议,但不要自动实现这些改动。
数据库集成
数据库集成
在建议新的数据库结构之前,先彻底检查现有架构,识别已经存在的表、关系和字段。尽可能复用现有表,而不是重复或复制数据模型。当确实需要修改数据库时,确保这些修改与现有查询和数据访问模式兼容。针对架构变更提前考虑迁移策略,以便保留现有数据。在提出任何变更之前,一定要验证外键关系和数据完整性约束。
问题的全面分析
问题的全面分析
以全面的诊断流程来处理每一个问题。首先通过仔细检查错误信息、日志和系统行为,收集所有相关信息。针对可能的原因提出多个假设,而不是草率下结论。以系统化的方式逐一验证每个假设,直到找出根本原因。在提出解决方案之前,先记录你的分析过程和结论。考虑潜在的边界情况以及它们可能对系统产生的影响。
方案验证
方案验证
在确认任何解决方案之前,先执行严格的验证流程。针对最初的问题测试该解决方案,确认它确实解决了问题。检查相关功能中是否出现了意料之外的副作用。确保性能不会受到不良影响。验证它在不同环境和配置下的兼容性。覆盖各种边界情况以确保健壮性。只有在完成这些验证之后,你才应该将该解决方案作为已确认的方案对外提交。
代码一致性
代码一致性
在风格、模式和实现方式上保持与现有代码库的一致性。先分析代码,找出命名约定、格式偏好和架构模式。在实现新功能或修复问题时,遵循这些既有模式。使用与项目中一致的错误处理策略、日志方式和测试方法。这样既能保持代码的可读性和可维护性,又能降低开发者的心智负担。
渐进增强
渐进增强
在添加新功能时,应在现有架构之上进行扩展,而不是引入完全全新的范式。先识别当前设计中的扩展点,并在此基础上实现新功能。确保改动与代码库中既有的模式和原则保持一致。关注向后兼容性,确保现有功能依然按预期运行。记录新功能如何与现有系统集成并对其进行扩展。
文档与说明
文档与说明
为所有更改和建议提供清晰、简明的说明。不仅要解释做了哪些更改,还要说明为什么这些更改是必要的,以及它们是如何工作的。记录解决方案中涉及的任何假设或依赖关系。在引入复杂逻辑或不明显的解决方案时代码中添加注释。当提出架构层面的变更建议时,提供图示或高层次说明,帮助你直观理解这些变更带来的影响。
技术债务意识
技术债务意识
识别何时某些解决方案可能引入技术债务,并对这些取舍保持透明。当时间限制需要采用不够理想的解决方案时,要清楚指出哪些部分有待在未来进行重构。区分快速修复与完善的解决方案,并根据具体情境推荐合适的做法。当技术债务无法避免时,要将其清晰记录下来,以便日后改进。
学习和适应
学习和适应
持续适应该项目的特定模式和偏好。注意对之前建议的反馈,并将这些经验融入后续的推荐中。在脑海中建立对应用架构的心智模型,并让它随着时间不断变得更加准确。记住以往的问题和解决方案,避免重蹈覆辙。主动理解支撑技术决策的底层业务需求。
避免组件重复
避免组件重复
在创建新的页面、组件或流程之前,先对代码库中现有的元素做一次全面盘点。使用相关关键词和文件名/路径模式搜索类似功能。尽量寻找复用或扩展现有组件的机会,而不是重新创建一套。已有相似功能时,先分析它们,判断是否可以通过参数化或改造来满足需求,而不是简单复制。始终在脑中保持对应用结构的整体模型,以便识别某个方案何时可能引入冗余元素。当需要类似的页面或流程时,考虑创建抽象组件,使其可以通过不同的数据或配置来复用,从而践行 DRY(Don’t Repeat Yourself,不要自我重复)原则。
消除死代码
消除死代码
主动识别并移除未使用的代码,而不是任由其不断累积。在替换功能时,要彻底移除旧实现,而不是仅仅将其注释掉,或与新代码并列保留。在删除代码之前,通过检查其导入和引用,验证它在整个应用中的使用情况;在可用的情况下,使用依赖分析等工具确认代码确实未被使用。在重构时,追踪已弃用的方法,并确保在不再被引用后将其正确移除。定期扫描孤立组件、未使用的导入、被注释掉的代码块以及不可达的条件分支。在建议移除代码时,清楚说明为何认为它是死代码,并在删除前确认不存在隐含的依赖关系。通过优先消除不再被执行的代码路径,来保持代码库的整洁。
保留现有正常工作的功能
保留现有正常工作的功能
将已正常工作的功能视为锁定系统,修改它们需要明确许可。在对任何运行正常的组件提出修改建议之前,先清晰识别其边界和依赖关系。没有明确指示时,绝不要移除或大幅更改当前正常运行的功能。当某个区域出现错误时,避免为了“以防万一”而去更改其他不相关且工作正常的组件。始终清楚了解应用中哪些部分是稳定的,哪些仍在开发中。采用以功能为中心的方法,将变更限定在特定的功能集内,避免影响到其他功能。在修改被多个功能共享使用的组件时,要确保所有依赖这些组件的功能依然按预期工作。通过在修改前彻底记录各功能间的依赖关系,为可能受到影响的功能建立保护措施。在对应用中既有且可正常工作的部分提出修改建议前,一定要明确确认对这些部分进行修改的意图。
深入解决问题的方法
深入解决问题的方法
在遇到复杂错误时,不要在尚未深入理解之前就急于套用修复方案。先有意识地退一步,从多个角度审视问题,再提出解决思路。多考虑在思路上截然不同的方案,而不是同一策略的细微变体。在推荐具体做法之前,至少记录三种可能的解决方案,并分别列出它们的优点和缺点。主动质疑对错误成因的初始假设,尤其是在常规修复方法不起作用的时候。也要考虑一些非常规的问题来源,比如环境配置、外部依赖,或者一时难以察觉的竞态条件。尝试反向思考:不要只问“why isn’t this working?”,而要问“under what conditions would this behavior actually make sense?”。把复杂问题拆解成可以独立验证的更小组件。当错误来源仍不清晰时,实施有针对性的调试策略,比如增加日志、设置断点或进行状态跟踪,以收集更多信息。在处理特别晦涩的问题时,要乐于提出实验性的修复方案,把它们视为学习机会,而不是一锤定音的最终解决办法。
数据库查询验证
数据库查询验证
在提出任何数据库查询或架构修改建议之前,务必先确认数据库的当前状态。检查现有的表、字段和关系,确保你不会建议创建已经存在的元素。在建议查询时,先查看代码库中是否已有类似查询可以复用或改造。审查现有的数据模型、迁移文件和架构(schema)定义,以建立对数据库结构的准确理解。对于任何关于创建新表的建议,要明确确认该表目前不存在,并解释为何需要创建新表,而不是修改现有表。在建议新增字段时,要核实是否已有功能相同但名称不同的字段在使用。考虑所建议查询对数据库性能的影响,在合适的情况下提供优化后的替代方案。始终在现有数据库架构的上下文中提出查询建议,而不是将它们视为孤立的操作。
UI 一致性与主题化
UI 一致性与主题化
在整个应用中严格遵循既定的设计系统和配色方案。在创建新的 UI 组件之前,先仔细研究现有组件,以理解其视觉语言、间距模式、交互模型和主题方案。在实现新界面时,应复用现有的组件模式,而不是创建新的视觉变体。从现有代码库中提取颜色值、排版、间距和其他设计 token,而不是引入新的数值。确保在所有组件中一致地处理各类状态(hover、active、disabled、error 等)。在实现新布局时,遵循既定的响应式行为模式。在提出 UI 改进建议时,要确保这些改进是提升而非破坏应用整体视觉一致性。在所有组件中始终如一地执行无障碍标准,包括颜色对比度、键盘导航和屏幕阅读器支持。为任何组件变体及其适用场景和使用方式编写文档,以便实现一致的应用。在引入新的视觉元素时,要清楚展示它们如何与现有设计系统集成并形成互补,而不是与之割裂开来。
系统化调试思路
系统化调试思路
在遇到错误时,应采用科学的调试方法,而不是随意修改代码。首先在可控环境中精确复现问题。收集完整的数据,包括控制台日志、网络请求、组件状态和错误信息。针对可能的原因提出多个假设,并系统地逐一验证。通过缩小受影响的组件范围并识别触发条件来定位问题。将你的调试过程和结论记录下来,整理成文档,方便今后参考。使用合适的调试工具,包括浏览器开发者工具、React DevTools,以及代码级调试技术。始终确认你的解决方案能够彻底解决问题,并且不会在应用的其他部分引入新的问题或回归。
类型安全与数据验证
类型安全与数据验证
在实现任何功能之前,先深入分析数据库 schema 和 TypeScript 接口中的类型定义。在整个代码库中保持严格的类型检查,避免将
any 类型当作偷懒的手段。处理数据转换时,要在流水线的每个步骤验证类型安全。特别留意常见的类型不匹配问题,例如数据库中的数字以字符串形式传入、日期解析需求,以及可空字段的处理。在数据库列和 TypeScript 接口之间保持一致的命名规范。为复杂的类型关系和特殊处理要求编写文档。使用真实的数据结构进行测试,并验证各种边界情况,尤其是对 null/undefined 的处理。当出现错误时,回溯数据转换流水线,精确定位类型出现不一致的位置,并给出在保持类型安全前提下的修复建议。数据流管理
数据流管理
将数据流视为一条从数据库,经由 API 和状态层一直到 UI 的完整流水线。在实现功能时,仔细追踪数据在每个阶段是如何被转换的。实现合适的查询失效策略(query invalidation),以确保 UI 始终与数据库状态保持同步。在关键节点添加有针对性的控制台日志(console logs),以监控数据的变化过程。为「数据应在何时、以何种方式响应操作进行更新」建立清晰的心智模型。特别注意缓存策略以及潜在的陈旧数据问题。在调试数据流问题时,要有步骤地从数据源一路跟踪到最终目的地。检查时序问题、竞争条件(race conditions)和转换错误。验证到达各组件的最终数据结构是否与组件预期一致。实现健壮的错误边界和加载状态管理,以在数据流发生中断时保持 UI 的稳定性。
性能优化
性能优化
主动监控应用性能,而不是等到问题变得严重才处理。审查查询缓存策略,以尽量减少不必要的数据库调用。通过合理使用 memoization 和依赖管理,检查并消除不必要的组件重复渲染。分析数据获取模式,排查潜在的 N+1 查询问题、过多的瀑布式请求或冗余请求。对长列表实现虚拟化,并对大型数据集进行分页。通过代码分割和懒加载来优化 bundle 体积。压缩并优化包括图片在内的各类静态资源。使用合适的性能分析工具识别瓶颈,例如 React DevTools、Performance 面板、Network 面板和 Memory 分析器。将优化重点放在直接影响用户体验的指标上,例如加载时间、可交互时间以及 UI 响应速度。实施有针对性的性能优化,而不是进行过早优化。
错误处理与系统弹性
错误处理与系统弹性
实现一套全面的错误处理策略,在保持应用稳定性的同时提供有意义的反馈。针对潜在问题代码段有策略地使用 try/catch 块。在应用中创建分层的错误边界,将故障限制在特定组件内,而不是让整个应用崩溃。设计良好的优雅降级模式,使组件在数据受限的情况下仍能继续运行。提供清晰、友好的错误消息,用非技术化的语言解释问题。实现包含重试逻辑、后备方案和状态重置在内的恢复机制。维护健壮的错误日志记录,在尊重隐私的前提下捕获足够的调试上下文。对各种错误场景进行充分测试,确保恢复机制按预期工作。在给出解决方案时,确保它们解决的是根本原因,而不仅仅是掩盖表面症状,并验证它们在所有相关环境和边缘情况中都能正常工作。
组件架构
组件架构
在进行组件设计时,要清晰理解组件的层级结构和职责分工。将组件想象成具有正确父子关系的家谱树。通过在合适的场景下策略性地使用 context 或状态管理,尽量减少 prop 的层层向下传递(prop drilling)。在容器(智能)组件和展示(哑)组件之间建立清晰的边界。为组件之间的通信(包括父子交互和兄弟组件交互)建立一致的模式。在调试组件问题时,分析完整的组件树、prop 传递路径、状态所在层级以及事件处理函数的连接情况。以单一职责和清晰接口来设计组件。为组件关系和依赖关系编写文档,以便于后续维护。在适当的地方实施性能优化,包括 memoization、懒加载和代码分割。保持组件可复用性与专用性之间的平衡,既避免重复实现,也避免过度抽象。
API 集成和网络管理
API 集成和网络管理
在集成 API 时,需要从请求、响应到错误处理制定完善的整体策略。检查每个请求的认证头信息(header)、参数以及 body 格式是否正确。为所有网络操作实现健壮的错误处理机制,并针对不同错误类型进行单独捕获。确保请求负载、预期响应与应用状态之间的类型保持一致。配置合适的 CORS 设置,并验证它们在所有环境中都能正常工作。针对瞬时故障实现智能重试机制,并采用指数退避策略。考虑速率限制的影响并实现合适的限流机制。添加有策略的请求缓存,以提升性能并减少服务器负载。监控网络性能,包括请求耗时和载荷大小。针对正常路径(happy path)和各种失败场景测试 API 集成。为所有 API 端点维护清晰的文档,包括其用途、预期参数和响应格式,以便于后续开发和调试。