摘要:摘要堆棧是的關(guān)鍵。假設(shè)捕獲了一個(gè)異常,上報(bào)的堆棧是這個(gè)這個(gè)堆棧,你看得出問題來嗎我們發(fā)布到的腳本文件,普遍是經(jīng)過壓縮的,所以堆棧可讀性相當(dāng)?shù)牟?。假如有下面的一個(gè)堆棧查看工具,又如何眼尖的同學(xué),一眼就能找到問題。
摘要: 堆棧是Debug的關(guān)鍵。
原文:如何優(yōu)雅地查看 JS 錯(cuò)誤堆棧?
作者:小芭樂
Fundebug經(jīng)授權(quán)轉(zhuǎn)載,版權(quán)歸原作者所有。
在前端,我們經(jīng)常會(huì)通過 window.onerror 事件來捕獲未處理的異常。假設(shè)捕獲了一個(gè)異常,上報(bào)的堆棧是這個(gè):
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)
這個(gè)堆棧,你看得出問題來嗎?我們發(fā)布到 CDN 的腳本文件,普遍是經(jīng)過 UglifyJS 壓縮的,所以堆??勺x性相當(dāng)?shù)牟?。假如有下面的一個(gè)堆棧查看工具,又如何?
眼尖的同學(xué),一眼就能找到問題。這里的 p[e] 出現(xiàn)了可能為 undefined 的情況。
這樣一個(gè)工具,大大提高了問題定位的效率。
好,這里不賣瓜,我們來看下這當(dāng)中的實(shí)現(xiàn)原理。
一步步來說的話:
拿到原始堆棧字符串,使用
error-stack-parser
解析為堆棧幀,每個(gè)堆棧幀包含三個(gè)最重要的字段:
url - 源碼的 URL 地址
line - 堆棧位置行號
col - 堆棧位置列號
對于 url,我們可以用于加載源碼內(nèi)容,得到 source
source 使用 UglifyJs 反向美化成多行的代碼 prettysource,并且同時(shí)生成 sourcemap
堆棧幀中的 line 和 col 通過 sourcemap 反查,得到美化后對應(yīng)的 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 對壓縮代碼進(jìn)行反向美化的核心代碼。下面給出 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
源碼只包含堆棧解析的實(shí)現(xiàn),UI 的實(shí)現(xiàn)不在本文的討論之內(nèi),用 React 隨便畫一畫就好了。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/109009.html
摘要:假設(shè)捕獲了一個(gè)異常,上報(bào)的堆棧是這個(gè)這個(gè)堆棧,你看得出問題來嗎我們發(fā)布到的腳本文件,普遍是經(jīng)過壓縮的,所以堆??勺x性相當(dāng)?shù)牟?。假如有下面的一個(gè)堆棧查看工具,又如何堆棧查看工具眼尖的同學(xué),一眼就能找到問題。 本文由云+社區(qū)發(fā)表 在前端,我們經(jīng)常會(huì)通過 window.onerror 事件來捕獲未處理的異常。假設(shè)捕獲了一個(gè)異常,上報(bào)的堆棧是這個(gè): TypeError: Cannot read...
摘要:假設(shè)捕獲了一個(gè)異常,上報(bào)的堆棧是這個(gè)這個(gè)堆棧,你看得出問題來嗎我們發(fā)布到的腳本文件,普遍是經(jīng)過壓縮的,所以堆棧可讀性相當(dāng)?shù)牟?。假如有下面的一個(gè)堆棧查看工具,又如何堆棧查看工具眼尖的同學(xué),一眼就能找到問題。 本文由云+社區(qū)發(fā)表 在前端,我們經(jīng)常會(huì)通過 window.onerror 事件來捕獲未處理的異常。假設(shè)捕獲了一個(gè)異常,上報(bào)的堆棧是這個(gè): TypeError: Cannot read...
摘要:假設(shè)捕獲了一個(gè)異常,上報(bào)的堆棧是這個(gè)這個(gè)堆棧,你看得出問題來嗎我們發(fā)布到的腳本文件,普遍是經(jīng)過壓縮的,所以堆棧可讀性相當(dāng)?shù)牟?。假如有下面的一個(gè)堆棧查看工具,又如何堆棧查看工具眼尖的同學(xué),一眼就能找到問題。 本文由云+社區(qū)發(fā)表 在前端,我們經(jīng)常會(huì)通過 window.onerror 事件來捕獲未處理的異常。假設(shè)捕獲了一個(gè)異常,上報(bào)的堆棧是這個(gè): TypeError: Cannot read...
摘要:二需要處理哪些異常對于前端來說,我們可做的異常捕獲還真不少??偨Y(jié)一下,大概如下語法錯(cuò)誤代碼異常請求異常靜態(tài)資源加載異常異常異??缬虮罎⒑涂D下面我會(huì)針對每種具體情況來說明如何處理這些異常。 前端一直是距離用戶最近的一層,隨著產(chǎn)品的日益完善,我們會(huì)更加注重用戶體驗(yàn),而前端異常卻如鯁在喉,甚是煩人。一、為什么要處理異常?異常是不可控的,會(huì)影響最終的呈現(xiàn)結(jié)果,但是我們有充分的理由去做這樣的事...
閱讀 2859·2021-11-25 09:43
閱讀 2502·2021-10-09 09:44
閱讀 2816·2021-09-22 15:49
閱讀 2589·2021-09-01 11:43
閱讀 2557·2019-08-30 14:16
閱讀 477·2019-08-29 17:24
閱讀 3031·2019-08-29 14:00
閱讀 1395·2019-08-29 13:05