热门搜索 :
考研考公
您的当前位置:首页正文

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

来源:东饰资讯网
如何优雅地查看 JS 错误堆栈?

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

TypeError: Cannot read property 'module' of undefined
 at Object.exec 
 at HTMLLIElement.<anonymous> 
 at HTMLDivElement.dispatch 
 at HTMLDivElement.y.handle 

这个堆栈,你看得出问题来吗?我们发布到 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领取更多资料】

Top