線上出bug了?別怕,這么定位!


摘要: Source Map還是很神奇的。

Fundebug經授權轉載並修改,版權歸原作者所有。

工作中,生產環境代碼是編譯后代碼,搜集到報錯信息的行和列無法在源碼中對應,很多時候只能靠“經驗”去猜,本文針對這種情況,開發了一個npm命令行小工具,幫助快速定位報錯的源碼位置,提升效率。

由於現在構建工具盛行,前端部署的代碼都是經過編譯,壓縮后的,於是乎,SoueceMap就扮演了一個十分重要的角色,用來作為源代碼和編譯代碼之間的映射,方便定位問題。

測試SourceMap功能

首先全局安裝reverse-sourcemap

npm install --global reverse-sourcemap

選擇編譯后的代碼進行測試,下面是vue項目編譯生成的代碼。

在命令行執行命令,將main.js反編譯回源碼,並輸出到sourcecode目錄下。

reverse-sourcemap -v dist/main.a8ebc11c3f03786d8e3b.js.map  -o sourcecode

上面是執行命令輸出的sourcecode目錄,生成的目錄結構和源碼目錄一致,打開一個文件,和源碼做下對比:

可以看出,反編譯出的代碼無論目錄結構還是具體代碼都和源碼一致。

生產環境代碼報錯如何定位源碼位置

如果使用了Fundebug的Source Map功能的話,則可以很方便的定位出錯位置:

如果沒有使用監控工具的話,生產環境的代碼,經過壓縮、編譯,很不利於Debug。針對這個問題,需要准備一份生產環境代碼的map文件,為了方便,可以在項目的package.json增加debug命令用來生成map文件。這條命令除了開啟sourcemap,其他的具體webpack配置和生產環境配置相同。

    "scripts": {
        "start": "vue-cli-service serve --mode dev",
        "stage": "vue-cli-service build --mode staging",
        "online": "vue-cli-service build",
        "debug": "vue-cli-service build --mode debug"
    }

有了map文件,通過SourceMap提供的API就可以定位到源碼的位置。下面是實現的核心代碼。

// Get file content
const sourceMap = require('source-map');
const readFile = function (filePath) {
  return new Promise(function (resolve, reject) {
    fs.readFile(filePath, {encoding:'utf-8'}, function(error, data) {
      if (error) {
        console.log(error)
        return reject(error);
      }
      resolve(JSON.parse(data));
    });
  });
};

// Find the source location
async function searchSource(filePath, line, column) {
  const rawSourceMap = await readFile(filePath)
  const consumer = await new sourceMap.SourceMapConsumer(rawSourceMap);
  const res = consumer.originalPositionFor({
    'line' : line,
    'column' : column
   });
   consumer.destroy()
  return res
}

最重要的就是使用SourceMap提供的 originalPositionFor API。 SourceMapConsumer.prototype.originalPositionFor(generatedPosition)

originalPositionFor API的參數為一個包含line和column屬性的對象
line 編譯生成代碼的行號,從1開始
column 編譯生成代碼的列號,從0開始
這個方法會返回一個具有以下屬性的對象

{
    "source": "webpack:///src/pages/common/403.vue?c891", // 源代碼文件的位置,如果無法獲取,返回null。
    "line": 4, // 源代碼的行號,從1開始,如果無法獲取,返回null。
    "column": 24, // 源代碼的列號,從0開始,如果無法獲取,返回null。
    "name": "get" // 源代碼的標識,如果無法獲取,返回null。
}

源碼定位工具

為了使用方便,我將這個功能做成了一個命令行小工具。全局安裝后,不需要做任何配置就可以使用。

安裝

npm install --global source-location

參數介紹

Usage: sl [options]

Options:
  -v, --version           output the version number
  -p, --source-flie-path  The generated source file  編譯后的map文件
  -l, --ine               The line number in the generated source  編譯后代碼行號
  -c, --column            The column number in the generated source  編譯后代碼列號
  -h, --help              output usage information

使用案例

終端執行命令:

sl -p dist/1.f47efcb58028826c7c05.js.map -l 1 -c 34 

命令行將會輸出:源碼的文件路徑:path,源碼行號:line,源碼標識:name。

項目的github地址: github.com/front-end-y… 如有錯誤歡迎指出。

最后,推薦大家使用Fundebug,一款很好用的BUG監控工具,支持Source Map功能~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM