Skip to content

ADR-240: 代码重复审计与双源消除 —— canvasToBase64 去重 / applyWindToParticles 空壳处置 / 工作区垃圾清理

状态: ✅ 已实施(2026-08-03 完成;P1 清理 + P2 双源消除 + P3 空壳删除落地,P4 暂缓) 日期: 2026-08-03

编号: 240

关联: ADR-191(core/utils 神桶下沉、零依赖叶纪律——本次为补漏执行)、ADR-017(A2-04 toBlob 异步编码——scene-menu 私有复制实现即其产物,去重不改行为)

来源: 2026-08-03 全仓重复代码审计(646 个 TS 文件 / 15.5 万行):重名函数扫描 + 双源 diff 校验 + 调用面核验。

决策者: Riku(联邦首席架构师 AI)、Jieling(人类侧首席架构师)

创建日期: 2026-08-03


1. 背景:审计发现三类可处置项

按 AGENTS.md「显著重复」标准(相似逻辑 ≥2 文件出现应抽取,UI builder 纯布局除外)全仓盘查:

级别位置事实(实测)
🔴 P1frontend/src/_reach*.cjs ×7、base_export/(7.6M)一次性探查脚本 + 误导出目录,全部未跟踪,迟早误提交
🟠 P2menus/scene-menu.ts:39 vs core/image.ts:13私有 canvasToBase64 与 ADR-191 下沉的零依赖叶逐字等价(diff 仅 FileReader 分支 if/else vs 三元风格漂移)——双源隐患:单侧修复即分叉
🟡 P3scene/env/env.ts:108 applyWindToParticlesenv-particles.ts:826 真实实现(ps: ParticleSystem同名空壳_wind: {x,y,z}),正文为空——实测无任何外部调用,纯误导性占位
🟢 P4menus/model-preset.ts:353 vs menus/preset-list-viewer.ts:156buildPresetListLevel同名不同义(无参专用 vs 泛型通用),导出名冲突易误用
✅ 合法env.ts 门面、camera.tscamera-state.tslipsync-bridge.tsperception.tscore/path.tslibrary/library-path.tscomputeLibraryRef 包装器)、测试 mock 重名均为刻意分层/适配器(注释明示),不合并——保持现状

非重复澄清:canUndo/buildLevel/getScene/setter 双份(setCameraControl/setFov/setLipSyncEnabled 等)均为同名不同义或状态层/行为层分层,非逻辑重复,不动。

2. 决策

  1. P1 清理:删除 _reach*.cjs ×7 与 base_export/.gitignorebase_export,防再犯。
  2. P2 双源消除scene-menu.ts 删除私有 canvasToBase64,改 import { canvasToBase64 } from '@/core/image'ar-camera.ts/thumbnail-capture.ts 已如此导入,签名一致,行为不变)。
  3. P3 空壳删除:删除 env.ts:108applyWindToParticles 空壳——无调用方,且与 env-particles.ts 真实实现重名构成陷阱(从 @/scene/env 导入会拿到空壳);真实风力路径在 env-particles.ts 内部自洽。
  4. P4 暂缓buildPresetListLevel 改名(如 buildModelPresetLevel)收益低、波及两文件引用,记录为后续可选,本次不执行。

3. 风险与对策

级别风险对策
🟡 P2scene-menu 改导入后签名/行为不一致两版本函数体已 diff 确认等价;改完跑 scene-menu 相关单测 + tsc --noEmit
🟡 P3空壳删除后若有隐藏调用方(字符串引用/动态导入)全仓 grep applyWindToParticles 核验仅 env-particles 内部 + env.ts 定义,无第三方引用;改后 npm run check:consumers -- applyWindToParticles 复核
🟢 P3清理误删用户进行中的测试文件model-preset.pbr.test.ts 等未跟踪测试文件不清理,仅清 _reach*.cjs/base_export/ 明确垃圾

4. 实施步骤

  1. P1:rm _reach*.cjs + rm -rf base_export + .gitignore 追加 base_export
  2. P2:scene-menu.ts 顶部加 import { canvasToBase64 } from '@/core/image',删除 39-69 行私有实现(两处调用点不动)
  3. P3:env.ts 删除 108-110 行空壳(env-particles.ts 真实实现不动)
  4. 验证:npm run check(tsc)+ scene-menu/env 相关单测
  5. 同步:npm run gen:status + npm run gen:docsindex + npm run check:docs
  6. 提交:仅 add 本次认领文件(ADR + scene-menu.ts + env.ts + .gitignore),不碰用户进行中文件