一、引言
“就改了一行工具函数,怎么有五个页面都受影响了?”
“这个组件的 props 我只是加了个可选值,线上怎么有个弹窗直接崩了?”
这些“意外”,大概是每个维护老项目的前端都经历过的。我们也遇到过不少这样的情况,开了很多次复盘会。逐渐让我们开始反思。
我们逐渐意识到,问题未必是“自测不够”,而是我们缺少一种在测试前评估风险的能力——代码影响范围分析。
二、传统 VS AI
我当时就在想一个问题:有没有办法,在写完代码之后,就能提前判断这次改动可能影响到哪些地方?
我们现在常用的方法,大致就这几类:
- 最基础的是在 VS Code 里全局搜索关键词,再结合对项目结构的理解和经验来判断哪些地方可能受影响。稍微高级一点的,会用一些基于 AST 的分析工具,试着梳理调用链或依赖关系。
这些方法确实在一些场景下能帮上忙,但它们的共同局限是:只能看到语法结构,难以理解语义层面的变更影响。
比如:
- 它们能告诉你: priceFormat 函数被 ProductList.vue 和 CartDetail.vue 调用了。但它们无法告诉你: 你把 price 的单位从“元”改成了“分”,这是一个高风险的语义变更,所有调用方的数据源头都必须同步调整,否则将导致灾难性的金额展示错误。
所以我开始好奇,AI 工具能不能补上这块短板?比如 Cursor,它有没有可能看懂“你到底改了什么”,甚至进一步去推断这次改动可能带来的连锁反应?
三、一次 MVP 尝试:用 Cursor 做代码影响范围分析
带着这个想法,我尝试构建了一个基于 Cursor 的代码影响范围分析的半自动化工具,流程图如下:
简单来说分三步:
第一步:提取 Code Diff
第一步是准备好改动内容,给 Cursor 一个清晰的输入。用 Node + Child_process 执行 Git 命令,提取当前分支相对于 origin/master 的改动,提取内容包括:
# 1. 获取改动的文件git diff origin/master --name-only# 2. 获取每个文件的具体 diff 内容git diff origin/master <file_path> > diffs/<file_name>.diff
这些 Diff 后面会作为 Prompt 的一部分喂给 Cursor。
第二步:构造“专家级” Prompt
光把 Diff 扔给 AI 没有意义,AI 不知道你想干嘛。于是我们设计了一个 Prompt 模板,用角色扮演 + 问题引导的方式,把 Cursor 带入“有经验的前端 + QA 工程师”这个角色里。
模板核心长这样:
# 角色: 你是vue2高级开发人员&QA专家你是一位拥有 10 年经验的高级开发人员,正在开发一个复杂的 Vue 2 项目。你的任务是进行严格的代码影响分析。## 任务基于提供的 Code diff,生成结构化的代码影响范围分析报告。## 分析重点- Vue 组件:props、$emit、mixins、computed、watch- 路由:页面跳转、路由守卫- API:接口调用、数据流- Vuex:状态管理、actions/mutations- 公共组件/工具函数的影响范围## 执行策略1. 解析 diff 提取关键变更2. 并行搜索:grep_search 精确查找 + codebase_search 语义分析3. 深入分析受影响文件4. 评估风险并给出验证建议---以下是我的 Vue2 项目代码变更 diff,请分析影响范围:{Code Diff}
在获取完Code Diff后,会将其动态拼接到 Prompt 中,构建出一个包含角色设定、任务目标和上下文信息的完整 Prompt。
第三步:把 Prompt 扔给 Cursor,让它来分析
最后,把生成的 Prompt 投喂给 Cursor,让它输出一份 Markdown 格式的代码影响范围分析报告。下面是一份示例输出:
代码影响范围分析修改内容将头像组件(src/components/user-item/avatar.vue)点击事件的emit事件名从 click 改为 clicktest。this.$emit('click', it)改为:this.$emit('clicktest', it)🔴 受影响的文件1. src/components/user-item/index.vue位置: 第16行<avatar class="avatar" :width="avatarSize" :src="user.headImgUrl" :alt="user.nickName" :borderImg="user?.avatarFrame" @click.stop="handleNav" <!-- ❌ 会失效 --> zz-sortId="1" zz-sortName="头像"/>影响: 头像点击跳转用户主页功能失效2. src/views/mine/index/index.vue位置: 第23行<avatar @click="goSetting" <!-- ❌ 会失效 --> class="avatar mine-wrap-header-avatar" width="156" :src="userInfo?.profilePhoto" :borderImg="userInfo?.avatarFrame" zz-sectionid="100" zz-sortId="6" zz-sortName="头像" :zz-backup="legoBackupStr">影响: 个人中心头像点击跳转设置页面功能失效3. src/views/group-chat/apply-confirm/index.vue位置: 第12行<avatar class="avatar" width="88" :src="record.profilePhoto" :borderImg="record?.avatarFrame" @click.stop="handleNav" <!-- ❌ 会失效 --> zz-sortId="1" zz-sortName="申请人头像"/>影响: 申请确认页面头像点击跳转用户主页功能失效✅ 不受影响的文件以下文件虽然使用了 avatar 组件,但没有监听 @click 事件,因此不会受到影响:src/components/product-card/widgets/user-info.vuesrc/components/post-card/index.vuesrc/components/group-card/index.vuesrc/views/mine/poster/index.vuesrc/views/group-chat/group-detail/index.vuesrc/views/market/goods-detail/index.vuesrc/views/market/goods-detail/widgets/area-navbar.vue以及其他所有只使用 avatar 组件进行展示而不监听点击事件的文件📋 总结受影响文件数量: 3个影响等级: 中等 - 功能性问题主要影响: 头像点击跳转功能失效建议: 如果要进行此修改,需要同时将这3个文件中的 @click 改为 @clicktest
四、使用体验:AI 能不能“看懂改动”?
从这次尝试来看,Cursor 的表现其实比我预期中要好一些。总结下来,有几个让我觉得“确实能用”的点:
👍 能力亮点:
- 依赖关系识别: 对函数调用、组件引用、Mixin等依赖关系的梳理还算准确。能理解语义层面的变更: 比如emit事件名变化这种,AI 能看出这是“高风险”改动,而不是简单的重命名。前置化风险预警: 像一次自动 Code Review,提前揭示逻辑、兼容性等潜在风险点。
👎 存在的问题:
- Token 成本高: 当改动范围较大时,Prompt 的 Token 成本会显著上升。以一次测试为例,Diff 涉及 4 个文件、约 380 行代码,加上必要的上下文补充和问题描述,最终 Prompt 长度接近 9,000 tokens。偶尔会“想太多”: AI 有时会给出冗余建议,且并非总是准确,仍需人工判断。尤其在涉及动态依赖或依赖文件过多的场景下,准确性存在不确定性。
五、总结
这次只是一次基础的尝试,但已经让我看到了 Cursor 在代码分析方面的潜力。
它虽然无法替你完成测试,但却能像一个可靠的 Reviewer 一样,帮你划定合理的测试范围,甚至在你遗漏时提醒:“这里也可能受影响,别忘了。”
比起只会“帮你写代码”的工具,Cursor 更像是一个具备阅读、分析和推理能力的智能伙伴。这次的探索只是个起点,希望能借这个案例,让大家看到 Cursor 在开发流程中的更多可能性。
转转研发中心及业界小伙伴们的技术学习交流平台,定期分享一线的实战经验及业界前沿的技术话题。关注公众号「转转技术」(综合性)、「大转转FE」(专注于FE)、「转转QA」(专注于QA),更多干货实践,欢迎交流分享~