在地页手风琴与全景图全空:事故复盘 + 未定义变量门禁

日期:2026-09-29 分支:bobo/v3-c-takeover 修复提交:0b8ebc1b 责任人:波波


一、现象

在地页顶部「图片手风琴」六片空白、其下图片整块不显示,控制台无任何报错,

页面其余部分(五维宫格、周边寺庙)正常。

二、根因

上一笔 880953c9(「拾起碎片」改造为「周边寺庙」)在重写 onLoad 时,

删掉了两个 const 定义,却保留了 setData 里的引用:

// 被删掉的两行
const panorama = 'https://img.kailashi.cn/assets/miniapp-static/v1/local-panorama.jpg'
const accordion = SLICE_TITLES

// 引用还在 → 运行时 ReferenceError
this.setData({ accordion, panorama, ... })

三层放大,缺一层都不会这么难查:

  1. 编译期静默:esbuild 只做语法解析,不查未定义变量,编译一路绿灯。
  2. 运行期静默:异常被同段的 .catch(() => this.setData({ loading: false })) 吞掉,

页面只是 loading 转 false,看不出失败。

  1. 视觉上像数据问题:手风琴空白 + 下方图片空白,第一反应是"接口没数据/图床 404",

实际代码根本没跑到渲染。

三、修复

  1. 恢复两处定义(local.ts:180-181)。
  2. 那个空 catch 改成会留痕:

```ts

}).catch((e: any) => {

console.error('[local] 在地页数据加载失败', e)

this.setData({ loading: false })

})

```

  1. 补门禁 scripts/check_ts_undefined.py,堵住第 1 层。

四、新门禁:check_ts_undefined.py

python3 scripts/check_ts_undefined.py              # 正常检查
python3 scripts/check_ts_undefined.py --self-test  # 反证(注入假未定义变量)

为什么不能直接 tsc -p tsconfig.json

项目 tsconfig.json 写死 types: ["miniprogram-api-typings"],该包未安装。

tsc 会先抛 TS2688: Cannot find type definition file 并中止整个编译,

一个文件都不检查 —— 命令行却表现为"0 错误"的假绿。这是本次差点被骗过去的第二个坑。

脚本自带一份 types: [] 的临时配置(.tsconfig.undefcheck.json,用完即删)绕开它。

为什么还要过滤白名单

types: [] 意味着小程序宿主全局符号全部缺失,产生固定噪音。实测全仓 277 条报错

100% 是宿主符号,真问题 0 条:

符号条数类型
wx162TS2304
WechatMiniprogram42TS2503
Component34TS2304
Page27TS2304
getCurrentPages10TS2304
App / getApp各 1TS2304

白名单写死在脚本里(HOST_GLOBALS / HOST_NAMESPACES),

出现白名单外的新名字一律视为真问题,人工确认后再决定是否补进白名单。

已做的双重反证(不反证不许信)

反证结果
注入 ghostVariableThatDoesNotExist抓到 TS2304 ✓
把 panorama 定义删回原样抓到 local.ts(181,33) TS18004 ✓
还原后复跑PASS,0 真问题 ✓

五、教训

前端仓的语法门禁必须补一层 tsc,否则这类断链式改动永远抓不到。

页面主数据加载上等于自断线索。全仓扫出 21 处 .catch(() => {}) 完全空体,

其中内容加载类的(hero-section / key-route / key-experience / today-card /

asset-grid 等)建议后续统一加一行 console.error,本次只改了在地页这一处。

得看"删的东西还有没有人用" —— 这正是 tsc 能自动兜住的地方。

六、现状

待推送队列 27 笔 = 波波 19 + 小冈 8,方案待用户拍板)。