近期接手了一个拥有悠久历史的小程序项目, 简而言之, 该有的都没有, 历史认证过的缺点都还在.
项目里有个诡异的现象就是有id字段经常会莫名的丢失.
项目历史悠久的副作用就是会有那么几次的骨干人员流失, 导致某些问题处于没人知道也没人敢动的地位. 而本次的爬坑之旅就是因为这个id丢失会导致很严重的后果.
通过对项目的基本了解和排查之后, 可以得出以下结论.
这是一个全局的id
id的存储和使用没有直接关联 (没有直接的import关系)
首先, 尝试全局搜索一下.

image
这个数量级不是手工+肉眼可以解决的问题. 因为没有直接的import关系, 导致大多数的分析工具都毫无用处. 尤其是编译时的静态检查工具.
思考之后, 通过Proxy对全局对象进行代理来捕获异常的赋值行为.
主要思路有两步:
- 把globalData替换成proxy
- 通过proxy监听对应的字段赋值行为
let handleGD = this.globalData;
Object.defineProperty(this, 'globalData', {
set(v) {
handleGD = new Proxy(
{...v},
{
get(target, key) {
return target[key];
},
set(target, key, next) {
if (key === 'id' && (!next || next === 'undefined')) {
try {
throw new Error();
} catch (error) {
wx.getApp().addActionRecord('id异常赋值', {
typeof: typeof next,
value: next,
stack: error.stack,
});
// errorlog('id异常赋值', error.stack ?? '')
}
}
target[key] = next;
return true;
},
},
);
},
get() {
return handleGD;
},
});
// eslint-disable-next-line no-self-assign
this.globalData = this.globalData;
至此, 就可以通过日志来分析具体问题了. 具体情况不再细表, 抓出了很多静态分析觉得不会有问题的语句. 说多了全是泪.