- 当前 Bug 的表现
1. 未使用插件时不会触发这个异常。
2. 使用插件时,全局的 `Object.setPrototypeOf` 会被覆写,并且覆写的方法没有按 ecma-262 的定义返回第一个传参的值。
3. 在实际应用中,如果使用了 babel 提前编译代码,会有大量依赖于 `Object.setPrototypeOf` 的方法无法按预期执行,例如使用了继承语法的代码会由于 https://github.com/babel/babel/blob/0859535b/packages/babel-helpers/src/helpers.js#L517-L546 中读取的 `Object.setPrototypeOf` 的返回值变成 `undefined` 而抛出异常。
4. 该异常的根源可以排查到是在小程序的 `appservice/__dev__/WAService.js` 中,经 VSCode - Format Document 反混淆后位于 4908-4913 行(不同的反混淆工具得出的具体的行数也不同),截图可参考:https://media.discordapp.net/attachments/410768182102589454/527489845140914178/unknown.png
value: function (e, t) { e.__proto__ = t }, configurable: !0 }) |
2018.12.27 补充:使用微信开发者工具的 Devtools 反混淆后位于 6040-6045L
- 预期表现
`Object.setPrototypeOf(o, p)` 应返回 `o`。
具体可查阅:
- https://www.ecma-international.org/ecma-262/6.0/#sec-object.setprototypeof
- https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf#Notes
- https://github.com/babel/babel/blob/0859535b/packages/babel-helpers/src/helpers.js#L444-L452
Object.setPrototypeOf ( O, proto )
When the setPrototypeOf function is called with arguments O and proto, the following steps are taken:
1. Let O be RequireObjectCoercible(O).
2. ReturnIfAbrupt(O).
3. If Type(proto) is neither Object nor Null, throw a TypeError exception.
4. If Type(O) is not Object, return O.
5. Let status be O.[[SetPrototypeOf]](proto).
6. ReturnIfAbrupt(status).
7. If status is false, throw a TypeError exception.
8. Return O.
例如改为:
function _setPrototypeOf(o, p) { o.__proto__ = p; return o; } |
- 复现路径
请使用下面的小程序代码片段复现
- 提供一个最简复现 Demo
小程序代码片段:
https://developers.weixin.qq.com/s/VWjLSXmb724n
当 app.json 中去除了 plugins 时,测试用例通过;当 app.json 中包含 plugins 时,测试用例不通过。
- 2018.12.27 第一次更新
有人处理吗?
这个问题的影响面很大,使用 babel 自行预编译代码的用户可能随时都会踩到这个雷。我是 tinajs 和 mina-webpack 的作者(社区里的用户大部分都会在项目中使用 babel),昨天从一位用户反馈的情况排查到这个问题,相关的讨论可以在这里查阅:
https://discordapp.com/channels/410768182102589451/410768182102589454
- 2018.12.27 第二次更新
我更新了测试用例的代码片段:https://developers.weixin.qq.com/s/zLmvOYmU7w4x
通过在 WAService.js:formatted - 6042 Line 打断点(可搜索 Object, 快速找到这个位置),然后点击模拟器界面中的「测试」按钮,可以确认问题代码确实就出在这一函数。
感谢反馈。在启用插件时,会激活基础库里面的一段插件处理逻辑。这段逻辑里处理了 setPrototypeOf 方法,具体原因正在调查中。
下一个基础库版本会修复这个问题。
跨问题求回复,看一下我问答
https://developers.weixin.qq.com/community/develop/doc/000262e7930fa0af0ae710b0a5b400