摘要: Source Map仍是很神奇的。javascript
Fundebug經受權轉載並修改,版權歸原做者全部。前端
工做中,生產環境代碼是編譯後代碼,蒐集到報錯信息的行和列沒法在源碼中對應,不少時候只能靠「經驗」去猜,本文針對這種狀況,開發了一個npm命令行小工具,幫助快速定位報錯的源碼位置,提高效率。vue
因爲如今構建工具盛行,前端部署的代碼都是通過編譯,壓縮後的,因而乎,SoueceMap就扮演了一個十分重要的角色,用來做爲源代碼和編譯代碼之間的映射,方便定位問題。java
首先全局安裝reverse-sourcemapwebpack
npm install --global reverse-sourcemap
選擇編譯後的代碼進行測試,下面是vue項目編譯生成的代碼。git
在命令行執行命令,將main.js反編譯回源碼,並輸出到sourcecode目錄下。github
reverse-sourcemap -v dist/main.a8ebc11c3f03786d8e3b.js.map -o sourcecode
上面是執行命令輸出的sourcecode目錄,生成的目錄結構和源碼目錄一致,打開一個文件,和源碼作下對比:web
能夠看出,反編譯出的代碼不管目錄結構仍是具體代碼都和源碼一致。vue-cli
若是使用了Fundebug的Source Map功能的話,則能夠很方便的定位出錯位置:npm
若是沒有使用監控工具的話,生產環境的代碼,通過壓縮、編譯,很不利於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功能~