為啥用sourceMap
這幾天在搞前端錯誤日志,做過線上發布的都知道,我們發布到生產環境的代碼,一般都有如下步驟:
- 壓縮混淆,減小體積
- 多個文件合並,減少
HTTP
請求數 - 通過編譯或者轉譯,將其他語言編譯成
JavaScript
這三個步驟,都使得實際運行的代碼不同於開發代碼,不管是 debug 還是捕獲線上的報錯,都會變得困難重重。
解決這個問題的方法,就是使用sourceMap
。
啥是sourceMap
簡單說,sourceMap
就是一個文件,里面儲存着位置信息。
仔細點說,這個文件里保存的,是轉換后代碼的位置,和對應的轉換前的位置。
有了它,出錯的時候,通過斷點工具可以直接顯示原始代碼,而不是轉換后的代碼。
部分瀏覽器支持該功能,拿chrome為例,更多工具>開發者工具>DevTools>Settings>Sources
sourceMap長啥樣
通過webpack、uglifyjs
等工具,我們可以使用 sourceMap
,這里不細說配置方法,可以看這里。
sourceMap
是一個map
文件,與源碼在同一個目錄下。
在壓縮代碼的最后一行,會有這樣的一個引用:
... //# sourceMappingURL=main.js.map
指向的就是我們的map
文件。
sourceMap
的格式如下:
{ "version": 3, // SourceMap的版本,目前為3 "sources": [ "../src/main.js" // 轉換前的文件,該項是一個數組,表示可能存在多個文件合並 ], "names": [ // 轉換前的所有變量名和屬性名 "add", "x", "y", "test", "console", "log" ], // 記錄位置信息的字符串 "mappings": "CAAA,WACI,IAAIA,IAAM,SAASC,EAAEC,GACjBC,OACAC,QAAQC,IAAIJ,EAAEC,IAElBF,IAAI,EAAE,IALV" }
來一個實際應用
為了突出主題,我這里用uglifyjs來壓縮代碼,並生成sourceMap,並且使用到頁面上(就不再使用webpack重量級工具來示例了)。
首先安裝uglifyjs,並去壓縮我們的代碼
uglifyjs ./src/main.js -o ./build/main.js --source-map url=main.js.map
src/main.js代碼如下
(function(){ var add = function(x,y){ test(); console.log(x/y) }; add(4,2); })()
壓縮完成后,會在build根目錄下生成,壓縮后的代碼和sourceMap文件
然后再頁面上引入壓縮后的代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> 測試 </body> <script src="./build/main.js"></script> </html>
運行項目,會發現有一個報錯,然后點擊報錯,會發現直接(通過sourceMap)定位到了源代碼中的位置,很方便調試
正式環境下,建議關掉sourceMap,因為會導致打包后的體積增加