(如果你對 source-map
有了解,但是不知道具體怎麼實現,操作,可以跳過前面的,直接看底部列列舉的參考文章)
大家都知道一般我們前端的JavaScript程式碼上線前都會壓縮,混淆處理,減小程式碼體積的同時還相對安全些,線上程式碼一般是這樣的
舉一個具體例子 原始碼是這樣的
.......
function buyVip(){
// 判斷是否購買的是已經購買過的自動續費商品
let { auto_renew } = this.vipData.vip;
if( !this.isIOS == auto_renew.expire_type){
console.log("you are ios vip")
}
}
.....
複製程式碼
壓縮後是這個樣子
this.buyVip(this.selectInfo)},buyVip:function(t){var e=this;localStorage.setItem("vip_buy_goods",(0,l.default)(t)),this.timer=setTimeout(function(){if(!e.loginState)return e.loginActiveRouter="payVipOrder",u.default.openViewByRouter("bridge://user/login"),!1;var i=e.vipData.vip.auto_renew;if(!e.isIOS&&e.isSelect&&i&&1==i.auto_renew&&t.expire_type==i.expire_type&&t.expire_val==i.expire_val){var n=1==i.platform?
複製程式碼
結果由於 auto_renew 是個null,程式碼報錯了,報錯資訊如下
{
message: "Cannot read property 'auto_renew' of undefined",
url: "http://xxx.com/vip.024973a2.js",
row:1,
col:876
}
複製程式碼
這樣你根據錯誤資訊來定位具體的程式碼很不容易,這個例子還有 auto_renew
這個關鍵字,能根據關鍵字查,有的是 Cannot read property [0] of undefined"
只看錯誤行數,開發小哥哥想哭,肉眼很難定位的具體問題的
哪怎麼樣才能定位到具體錯誤啊?
要不不壓縮程式碼,直接原始碼上,這是不可能的,程式碼體積太大,安全也是個大問題,那我們在本地開發的時候,預設也是打包後的檔案,用Chrome 咋就能看到原始碼,其實就是利用的 SourceMap 技術來除錯,SourceMap簡單的講,就是維護一個原始碼和壓縮後程式碼一一對應的檔案,通過壓縮後的錯誤資訊反向推出原始碼錯誤具體行號,剛才上面那段程式碼,map檔案如下
{
"version": 3,
"sources": ["vip.024973a2.js"],
"names": ["buyVip",],
"mappings": "AAAA,QAASA,KAEL,GACIC,GAAW,UAAYC,IAC3BC,SAAQC,IAAIH,GAGhBD",
"file": "hello.min.js",
"sourceRoot": "",
"sourcesContent": ["function buyVip()\n{\n let { auto_renew } = this.vipData.vip\n ...."]
}
複製程式碼
這裡面的主要點是 mapings,是一個很長的字串,它分成三層,記錄了壓縮前後程式碼對行關係,具體map怎麼記錄的可以參考文章末尾的參考文章
那現在前端打包工具(webpack,gulp,rollup)都支援這個SourceMap功能,打包後類似這樣
我們需要做的是把 打包後的 SourceMap 檔案儲存起來,然後根據上報的錯誤資訊來反推具體行號了,強調下 SourceMap 檔案是不要跟著打包後的js一起部署的,這樣你線上的程式碼人家是很容易拿到的,相當於裸笨,所以需要在打包指令碼做文章,把 .js 和 .map 檔案獨立出來,看個圖(圖是從網上找到,參見參考文件)
這樣在錯誤平臺就能展示錯誤了
錯誤的展示平臺,我們用的 Node.js 實現的,Firefox 開源一個source-map
的包,非常好用,具體可以看github,
實際上 source-map
是一套成熟的技術,網上資料很多,可以搜來看看
那這裡僅僅是完成了一個最小的程式碼錯誤復現的閉環,
如何在gitlab ci 裡統一剝離 source-map 檔案和壓縮後 js 檔案,如何對多專案source-map 檔案儲存,如何對單專案多版本制定儲存規則,都是需要考慮的
第一個 統一剝離,因為我們公司的前端部署是統一的部署指令碼的,所以在公共的指令碼里做了處理,這也說明了,前端有統一的部署是多重要,不然單獨專案接,會把人煩死,專案多了,一定要,工程化,流程化,統一化
版本儲存規則,目前是 專案名/gittag/
還有一個問題是 source-map 檔案其實挺大的,而且是不變的,在Node.js 最好用Redis快取,我們初期專案接入不多,我先在記憶體裡做了快取
這個最小的閉環已經能很好的協助解決JavaScript 錯誤問題,但是還不能做到頁面的監控,
- 頁面錯誤的歸類
- 比方某天客服反應 ,武漢這個區域,大面積使用者報錯,或者是頁面直接打不開
- 根據手機平牌,時間點,地域,來篩選錯誤
- 某個使用者出現錯誤的前10秒,使用者都有哪些操作行為
- 網路請求大面積報錯
- CDN載入失敗
這些都是需要解決的問題,出現了問題,怎麼樣預警,通知到開發,是不是能做到智慧的處理,都是後面需要考慮的,所以還有很多工要做,有了新的進展,我會同步記錄下來。
插一句哈,Vue 丟擲的異常是沒有具體行號的,需要經過處理才能上報上去,可以在github搜下 github.com/occ/TraceKit
,專門格式化異常的(吐槽下中文搜尋到 處理 source-map 的文章,都是一樣的還互相抄,說到Vue錯誤處理都是直接跳過,要處理Vue異常的一定記得看下這個庫,幫助很大)
這周九天班,趕緊睡覺去了。
參考文章: