釋出以後,線上報錯了,咋辦?有沒有很恐慌?
每次上線都戰戰兢兢得生怕出錯,又得搞到凌晨一兩點,煩死了?這是不是你的現狀?作為一名資深程式設計師,我深知大家得不容易,所以今天奉上一本解決現場問題得法寶。具體如下:
(方法千變萬化,沒有最好,只有更好,如果大家有更好得辦法可以在評論區共同探討,共同成長,謝謝!)
上線以後,為什麼會出現問題?
問題來源有2種:
1.現場資料更加複雜,在uat測試階段,由於資料相對比較簡單,測試人員得臨界值設定得並不準確,導致bug沒有找出來。
2.前端程式碼有問題,在測試的時候沒有測試出來,釋出以後發現了。
解決辦法:
第一: 假設這就是後端資料問題,我們需要用一個chrome 外掛: Ajax-intercetion
下載:直接執行
git clone https://github.com/YGYOOO/ajax-interceptor.git
下載下來以後,直接拉進chrome的外掛裡面就好了,當然你也可以從chrome 的外掛商店裏麵直接下載,我的window10的chrome的外掛商店被攔截了,進不去,只能從倉庫裡面獲取。不管從哪裏獲取,拿到就好,無需較真。最後你可以得到如圖所示的標誌:
1.把需要攔截的介面地址輸入ajax-interceptor的 url 的設定裡面,然後重新整理頁面,觸發相關功能。
2.在chrome的devtool裡面的network裡面找到相關介面的資料,直接ctrl+A複製response
3.把上面複製好的響應資料放到 ajax-interceptor 的 replace Response with 裡面,然後把你覺得異常資料找到,改成合理的資料,然後觸發相關功能,你修改後的資料就會展示到頁面上。此時就能斷定是不是資料問題了。
如果你不會用,沒有關係,我為大家找了一個說明影片,大家可以點進去看看:
4.經過我們一系列的騷操作,終於發現不是資料問題呀,有沒有想死的心都有了?
第二:現在斷定一定是程式碼的bug, 可是線上錯誤指向的是一個壓縮檔案呀,咋辦?
想解決個bug,咋就這麼難呢?心裏噴涌而出的草泥馬,算了,不抱怨了,爲了早點下班,還是老老實實想一下解決辦法,纔是正事,你說對不對!我也不兜圈子了看下面。
線上無法除錯的根本原因就是沒有 suorcemap 唄,說白了就是打包的時候我們配的是 hidden-source-map,而不是source-map,他們的區別是啥?
首先 hidden-source-map 和 source-map 在打包的時候都會產生一個 .map 檔案,而且他們處理後的檔案大體是一樣的,唯一的區別就是source-map處理後的檔案下面多了一行程式碼,如圖所示:
我做了個測試程式碼,一個用source-map打包,一個用hidden-source-map打包,結果如下
用http-server將他們同時啟動
進入頁面看看
明顯他們的目錄訪問目錄不一樣,是不是?解決問題的根本就是把index.js和index.js.map用 //# sourceMappingURL=index.js.map關聯在一起,他們就能找到原始碼了,我們就可以歡樂的除錯它了,對不對?
方法1.利用chrome的 add sourcemap 功能,如下:
設定add sourcemap的檔案的時候,你可以連本地的,反正是對應的.map檔案就好了,如果沒有出來,一定是你的地址不對,趕緊改路徑吧。
此時8081的頁面和8082的頁面就一摸一樣了,你是不是就可以開心的除錯了呢,一眼看過去就能知道,線上到底是哪一行在報錯。
方法2.手動對映
1.在專案裡面安裝source-map庫
npm i source-map -D
2.在專案裡面建立一個source.js檔案
只需要修改紅框的地方即可,操作如下:
const { SourceMapConsumer } = require('source-map') const fs = require('fs') const rawSourceMap = fs.readFileSync('./dist/index.js.map', 'utf-8') // 填入錯誤資訊 originalPositionFor('index.js:1:161') function originalPositionFor(errInfo) { const [budleName, line, column] = errInfo.split(':') SourceMapConsumer.with(rawSourceMap, null, (consumer) => { const originalPosition = consumer.originalPositionFor({ line: parseInt(line), column: parseInt(column), }) console.log('bundle name = ', budleName) console.log('original position = ', originalPosition) }) }
是不是很美麗呀!
方法3. 用Charles代理
其實代理的目的就是對原始檔進行攔截,然後在response的檔案裡面加上//# sourceMappingURL=index.js.map,此時的url你可以寫線上的map檔案,也可以指定本地檔案對應的.map檔案,也就是說,
可以這樣://# sourceMappingURL=index.js.map
也可以這樣://# sourceMappingURL=http://127.0.0.1/index.js.map
具體如下:
設定斷點地址
2.如果此時Charles沒有工作,很可能是因為你chrome的代理外掛沒有關閉,關閉就可以正常工作了。
其實精髓就是要index.js和index.js.map連線起來,當然對面的大神們,你們肯定有更好的解決方法,不防在評論區說下,我來給大家補充全面,必經程式的發展本就靠的是大家的集思廣益,不是單打獨鬥!
謝謝!