启用插件时,Object.setPrototypeOf 被设为了错误的函数
- 当前 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 [代码]// WAService.js 4908-4913L[代码] [代码] [代码] [代码]Object.defineProperty(o.Object, [代码][代码]"setPrototypeOf"[代码][代码], {[代码] [代码] [代码][代码]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, 快速找到这个位置),然后点击模拟器界面中的「测试」按钮,可以确认问题代码确实就出在这一函数。