美文网首页
如何优雅地查看 JS 错误堆栈?

如何优雅地查看 JS 错误堆栈?

作者: 48730ba83b2d | 来源:发表于2019-01-25 20:15 被阅读0次
    如何优雅地查看 JS 错误堆栈?

    在前端,我们经常会通过 window.onerror 事件来捕获未处理的异常。假设捕获了一个异常,上报的堆栈是这个:

    TypeError: Cannot read property 'module' of undefined
     at Object.exec (https://my.cdn.com/dest/app.efe91e855d7432e402545e7d6c25d2d9.js:16:29828)
     at HTMLLIElement.<anonymous> (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 压缩的,所以堆栈可读性相当的差。假如有下面的一个堆栈查看工具,又如何?

    如何优雅地查看 JS 错误堆栈?

    堆栈查看工具

    眼尖的同学,一眼就能找到问题。这里的 p[e] 出现了可能为 undefined 的情况。

    这样一个工具,大大提高了问题定位的效率。

    好,这里不卖瓜,我们来看下这当中的实现原理。

    如何优雅地查看 JS 错误堆栈?

    堆栈工具实现原理

    一步步来说的话:

    • 拿到原始堆栈字符串,使用
    • 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 错误堆栈?

    【关注作者了解更多的好文,加群733234221领取更多资料】

    相关文章

      网友评论

          本文标题:如何优雅地查看 JS 错误堆栈?

          本文链接:https://www.haomeiwen.com/subject/jivvjqtx.html