vscode原生不支持语义级重复检测,需插件+人工协同:先用codemirror duplicate finder调低minlines(如4)、similaritythreshold(如70)并开启includestrings扫描显性重复;再通过正则搜共性骨架(如api路径、校验模式)结合diffchecker比对变体重复,同时检查.gitignore/files.exclude排除目录及边界文件。

重构后残留的重复代码,不是没改干净,而是工具没扫到——VSCode 原生不识别语义重复,Find in Files 搜不到变量名一换就失效的逻辑块,Ctrl+Shift+F 也抓不住 JSX 里换行缩进不同的模板字符串。检测必须分两层:先用插件筛出“显性重复”,再靠人工+正则揪出“变体重复”。
为什么重构后还会漏掉重复代码
重构常聚焦单点(比如抽一个 validatePagination 函数),但工具不会自动回溯所有调用方是否已切换过去。更麻烦的是,原逻辑可能被复制粘贴后微调过,变成“看起来不同、实则雷同”的变体:
-
axios.get(`/api/users/${id}`)和fetch(`/api/users/${id}`)—— 协议不同,但路径构造、错误处理结构一致 - 一处写
if (!data) return null;,另一处写if (!payload) { throw new Error(); }—— 校验逻辑本质相同,仅副作用差异 - 重复块被包裹在
useEffect或getServerSideProps中,插件默认跳过函数体内部扫描
CodeMirror Duplicate Finder 配置要调这三项
它默认只扫连续 8 行、相似度 ≥85% 的纯文本块,对重构后的残余毫无感知。必须手动收紧阈值:
- 把
duplicate-finder.minLines改成4:小钩子、校验逻辑常就 4–6 行 - 把
duplicate-finder.similarityThreshold调到70:变量名、空格、注释位置一动,相似度就掉,70 才能捕获微调后的变体 - 开启
duplicate-finder.includeStrings:否则template`/api/${type}/${id}`这类动态路径永远扫不到
改完配置后,右键 → Find Duplicates in Workspace,结果分组出现在侧边栏。注意:它不标“哪处是旧的、哪处是新的”,只告诉你“这三处长得像”——你得自己比对上下文,确认是否属于重构遗漏。
用正则 + 分组替换定位“伪差异”重复
当插件失效时,Ctrl+Shift+F 开正则模式(点 .* 图标)是最准的兜底手段。关键不是搜死字符串,而是抓共性骨架:
- 搜 API 路径构造:
/api/[^`'"]+/[^`'"]+—— 匹配所有/api/users/123、/api/orders?id=类路径,不管用反引号还是双引号 - 搜参数校验模式:
if\s*\(\s*(!?[\w.]+)\s*(==|===|\?\?)\s*(null|undefined)\s*\)—— 抓所有空值检查变体 - 搜 fetch/axios 封装:
(axios\.(get|post)|fetch\()\s*\([^)]+\)—— 统一命中两种请求方式
搜出来后,把几处结果复制进 diffchecker.com 对比。别信“只有 1 行不同”,重点看控制流分支、数据转换链、错误处理位置是否一致——这些才是决定是否该合并的核心。
重构后最易被忽略的重复藏在哪
不是 src/utils 下的 helper 文件,而是边界位置:测试文件里 copy-paste 的 mock 数据、CI 脚本中硬编码的路径、甚至 .gitignore 里被排除的 config 目录下——这些地方插件默认不扫,files.exclude 或 .gitignore 一旦排除了目录,Find Duplicates in Workspace 就彻底盲区。重构完务必检查:settings.json 里的 files.exclude 是否临时关掉了 **/tests/**,.gitignore 是否漏写了 src/config/。真要扫全,得手动在终端跑:simian -includes="**/*.ts,**/*.js" -threshold=70,它比 VSCode 插件更宽容,连空格和换行差异都算进相似度。











