摘要:摘要堆栈是的关键。假设捕获了一个异常,上报的堆栈是这个这个堆栈,你看得出问题来吗我们发布到的脚本文件,普遍是经过压缩的,所以堆栈可读性相当的差。假如有下面的一个堆栈查看工具,又如何眼尖的同学,一眼就能找到问题。
摘要: 堆栈是Debug的关键。
原文:如何优雅地查看 JS 错误堆栈?
作者:小芭乐
Fundebug经授权转载,版权归原作者所有。
在前端,我们经常会通过 window.onerror 事件来捕获未处理的异常。假设捕获了一个异常,上报的堆栈是这个:
TypeError: Cannot read property "module" of undefined at Object.exec (https://my.cdn.com/dest/app.efe91e855d7432e402545e7d6c25d2d9.js:16:29828) at HTMLLIElement.(https://my.cdn.com/dest/app.efe91e855d7432e402545e7d6c25d2d9.js:25:6409) at HTMLDivElement.dispatch (https://my.cdn.com/dest/vendor.eb28ded1876760b8e90973c9f4813a2c.js:1:248887) at HTMLDivElement.y.handle (https://my.cdn.com/dest/vendor.eb28ded1876760b8e90973c9f4813a2c.js:1:245631)
这个堆栈,你看得出问题来吗?我们发布到 CDN 的脚本文件,普遍是经过 UglifyJS 压缩的,所以堆栈可读性相当的差。假如有下面的一个堆栈查看工具,又如何?
眼尖的同学,一眼就能找到问题。这里的 p[e] 出现了可能为 undefined 的情况。
这样一个工具,大大提高了问题定位的效率。
好,这里不卖瓜,我们来看下这当中的实现原理。
一步步来说的话:
拿到原始堆栈字符串,使用
error-stack-parser
解析为堆栈帧,每个堆栈帧包含三个最重要的字段:
url - 源码的 URL 地址
line - 堆栈位置行号
col - 堆栈位置列号
对于 url,我们可以用于加载源码内容,得到 source
source 使用 UglifyJs 反向美化成多行的代码 prettysource,并且同时生成 sourcemap
堆栈帧中的 line 和 col 通过 sourcemap 反查,得到美化后对应的 prettyline 和 prettycol
将 prettysource、prettyline、prettycol 给到 Monaco Editor 渲染,就可以得到上述截图的效果
说那么多,不如贴代码是吧:
var result = UglifyJS.minify(source, { output: { beautify: true }, sourceMap: { filename: "pretty.js", url: "pretty.js.map" } }); var code = result.code; var rawSourceMap = JSON.parse(result.map); var consumerPromise = new sourceMap.SourceMapConsumer(rawSourceMap); resolve( consumerPromise.then(function(consumer) { return { code: code, sourceMapConsumer: consumer } }) );
上面就是使用 UglifyJs 对压缩代码进行反向美化的核心代码。下面给出 SourceMap 的使用源码:
var code = result.code; var consumer = result.sourceMapConsumer; var position = consumer.generatedPositionFor({ source: "0", line: lineNumber, column: columnNumber }); parent.postMessage({ event: "js-prettify-callback", payload: { hash: payload.hash, result: "success", prettySource: code, prettyLineNumber: position.line, prettyColumnNumber: position.column + 1 } }, sourceOrigin);
完整源码有兴趣的读者也可以下下来把玩把玩:
js-loader.html.zip
源码只包含堆栈解析的实现,UI 的实现不在本文的讨论之内,用 React 随便画一画就好了。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/109009.html
摘要:假设捕获了一个异常,上报的堆栈是这个这个堆栈,你看得出问题来吗我们发布到的脚本文件,普遍是经过压缩的,所以堆栈可读性相当的差。假如有下面的一个堆栈查看工具,又如何堆栈查看工具眼尖的同学,一眼就能找到问题。 本文由云+社区发表 在前端,我们经常会通过 window.onerror 事件来捕获未处理的异常。假设捕获了一个异常,上报的堆栈是这个: TypeError: Cannot read...
摘要:假设捕获了一个异常,上报的堆栈是这个这个堆栈,你看得出问题来吗我们发布到的脚本文件,普遍是经过压缩的,所以堆栈可读性相当的差。假如有下面的一个堆栈查看工具,又如何堆栈查看工具眼尖的同学,一眼就能找到问题。 本文由云+社区发表 在前端,我们经常会通过 window.onerror 事件来捕获未处理的异常。假设捕获了一个异常,上报的堆栈是这个: TypeError: Cannot read...
摘要:假设捕获了一个异常,上报的堆栈是这个这个堆栈,你看得出问题来吗我们发布到的脚本文件,普遍是经过压缩的,所以堆栈可读性相当的差。假如有下面的一个堆栈查看工具,又如何堆栈查看工具眼尖的同学,一眼就能找到问题。 本文由云+社区发表 在前端,我们经常会通过 window.onerror 事件来捕获未处理的异常。假设捕获了一个异常,上报的堆栈是这个: TypeError: Cannot read...
摘要:二需要处理哪些异常对于前端来说,我们可做的异常捕获还真不少。总结一下,大概如下语法错误代码异常请求异常静态资源加载异常异常异常跨域崩溃和卡顿下面我会针对每种具体情况来说明如何处理这些异常。 前端一直是距离用户最近的一层,随着产品的日益完善,我们会更加注重用户体验,而前端异常却如鲠在喉,甚是烦人。一、为什么要处理异常?异常是不可控的,会影响最终的呈现结果,但是我们有充分的理由去做这样的事...
阅读 2814·2021-11-25 09:43
阅读 2434·2021-10-09 09:44
阅读 2779·2021-09-22 15:49
阅读 2520·2021-09-01 11:43
阅读 2522·2019-08-30 14:16
阅读 428·2019-08-29 17:24
阅读 3007·2019-08-29 14:00
阅读 1358·2019-08-29 13:05