使用 Node.js 的源代碼映射 (Sourcemap) 在報錯時定位開發(fā)代碼及打印上下文

在前端開發(fā)中锁保,當源碼在生產(chǎn)環(huán)境報錯時,我們通常會遇到難以理解的壓縮代碼吴菠。然而浩村,借助Source Map技術(shù),并結(jié)合報錯堆棧信息或報錯行列信息心墅,我們可以使用Node.js來精確定位源碼報錯的位置。本文將介紹兩種方式瘫筐,一種是通過傳入報錯堆棧的方式严肪,另一種是通過報錯行數(shù)和列數(shù)定位谦屑,同時還會展示如何打印出報錯位置上下10行的上下文。

1. 通過傳入報錯堆棧定位

當瀏覽器控制臺顯示報錯堆棧時酝枢,我們可以借助第三方模塊(stackTraceParser)來解析報錯堆棧悍手,并提取出報錯文件坦康、行數(shù)和列數(shù)等信息。

示例代碼:

const fs = require('fs');
const { SourceMapConsumer } = require('source-map');
const stackTraceParser = require('stacktrace-parser');

// 讀取壓縮代碼和對應的Source Map
const compressedCode = fs.readFileSync('compressed.js', 'utf-8');
const sourceMap = fs.readFileSync('compressed.js.map', 'utf-8');

// 解析報錯堆棧古胆,獲取報錯文件、行數(shù)和列數(shù)信息
const errorStack = parseErrorStack(); // 解析錯誤堆棧
const errorLine = errorStack[0].lineNumber;
const errorColumn = errorStack[0].columnNumber;

// 解析Source Map文件
SourceMapConsumer.with(sourceMap, null, consumer => {
  // 在源碼堆棧中定位報錯位置
  const originalPosition = consumer.originalPositionFor({
    line: errorLine,
    column: errorColumn
  });

  // 輸出源碼報錯位置
  console.log('Error occurred at:');
  console.log(`- File: ${originalPosition.source}`);
  console.log(`- Line: ${originalPosition.line}`);
  console.log(`- Column: ${originalPosition.column}`);

  // 打印報錯位置上下10行的上下文
  const lines = fs.readFileSync(originalPosition.source, 'utf-8').split('\n');
  const startLine = Math.max(0, originalPosition.line - 10);
  const endLine = Math.min(lines.length - 1, originalPosition.line + 10);
  console.log('Error context:');
  for (let i = startLine; i <= endLine; i++) {
    console.log(`${i + 1}: ${lines[i]}`);
  }
});

// 解析報錯堆棧筛璧,提取報錯文件逸绎、行數(shù)和列數(shù)信息
function parseErrorStack() {
  const error = new Error();
  const parsedStack = stackTraceParser.parse(error);
  return parsedStack;
}

在上述示例中,我們首先使用fs模塊讀取壓縮代碼和對應的Source Map夭谤。然后棺牧,我們使用stackTraceParser模塊解析報錯堆棧,提取出報錯文件朗儒、行數(shù)和列數(shù)等信息颊乘。

接下來,我們使用SourceMapConsumer對象來解析Source Map文件醉锄,并根據(jù)報錯行數(shù)和列數(shù)找到源碼報錯的位置疲牵。最后,我們將得到的源碼報錯位置進行輸出纲爸,并打印出報錯位置上下10行的上下文。

2. 通過報錯行數(shù)列數(shù)定位

除了使用報錯堆棧外妆够,我們還可以直接使用報錯行數(shù)和列數(shù)信息识啦,通過映射Source Map定位源碼報錯的位置负蚊。

示例代碼:

const fs = require('fs');
const { SourceMapConsumer } = require('source-map');

// 讀取壓縮代碼和對應的Source Map
const compressedCode = fs.readFileSync('compressed.js', 'utf-8');
const sourceMap = fs.readFileSync('compressed.js.map', 'utf-8');

// 報錯文件的行列信息
const errorFile = 'compressed.js';
const errorLine = 10;
const errorColumn = 5;

// 解析Source Map文件
SourceMapConsumer.with(sourceMap, null, consumer => {
  // 在源碼堆棧中定位報錯位置
  const originalPosition = consumer.originalPositionFor({
    line: errorLine,
    column: errorColumn
  });

  // 輸出源碼報錯位置
  console.log('Error occurred at:');
  console.log(`- File: ${originalPosition.source}`);
  console.log(`- Line: ${originalPosition.line}`);
  console.log(`- Column: ${originalPosition.column}`);

  // 打印報錯位置上下10行的上下文
  const lines = fs.readFileSync(originalPosition.source, 'utf-8').split('\n');
  const startLine = Math.max(0, originalPosition.line - 10);
  const endLine = Math.min(lines.length - 1, originalPosition.line + 10);
  console.log('Error context:');
  for (let i = startLine; i <= endLine; i++) {
    console.log(`${i + 1}: ${lines[i]}`);
  }
});

在上述示例中,我們同樣使用fs模塊讀取壓縮代碼和對應的Source Map文件颓哮,并聲明報錯行數(shù)和列數(shù)信息家妆。然后,我們使用SourceMapConsumer對象來解析Source Map文件冕茅,并根據(jù)報錯行數(shù)和列數(shù)找到源碼報錯的位置伤极。

最后,我們將得到的源碼報錯位置進行輸出姨伤,并打印出報錯位置上下10行的上下文哨坪。

通過以上兩種方式,我們可以使用Node.js解析Source Map乍楚,并通過傳入報錯堆椀北啵或報錯行列信息來定位源碼報錯位置。同時徒溪,我們還展示了如何打印出報錯位置上下10行的上下文忿偷,以便更好地理解錯誤發(fā)生的上下文環(huán)境。

最終實現(xiàn)效果:

img_v2_7d6382f6-ffe1-495d-90bd-6a29dc7a431g.jpg

image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末臊泌,一起剝皮案震驚了整個濱河市鲤桥,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌渠概,老刑警劉巖茶凳,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異高氮,居然都是意外死亡慧妄,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門剪芍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來塞淹,“玉大人,你說我怎么就攤上這事罪裹”テ眨” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵状共,是天一觀的道長套耕。 經(jīng)常有香客問我,道長峡继,這世上最難降的妖魔是什么冯袍? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上康愤,老公的妹妹穿的比我還像新娘儡循。我一直安慰自己,他們只是感情好征冷,可當我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布择膝。 她就那樣靜靜地躺著,像睡著了一般检激。 火紅的嫁衣襯著肌膚如雪肴捉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天叔收,我揣著相機與錄音齿穗,去河邊找鬼。 笑死今穿,一個胖子當著我的面吹牛缤灵,可吹牛的內(nèi)容都是我干的伦籍。 我是一名探鬼主播蓝晒,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼帖鸦!你這毒婦竟也來了芝薇?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤作儿,失蹤者是張志新(化名)和其女友劉穎洛二,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體攻锰,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡晾嘶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了娶吞。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片垒迂。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖妒蛇,靈堂內(nèi)的尸體忽然破棺而出机断,到底是詐尸還是另有隱情,我是刑警寧澤绣夺,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布吏奸,位于F島的核電站,受9級特大地震影響陶耍,放射性物質(zhì)發(fā)生泄漏奋蔚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一烈钞、第九天 我趴在偏房一處隱蔽的房頂上張望泊碑。 院中可真熱鬧产上,春花似錦、人聲如沸蛾狗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽沉桌。三九已至谢鹊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間留凭,已是汗流浹背佃扼。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蔼夜,地道東北人兼耀。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像求冷,于是被迫代替她去往敵國和親瘤运。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容