前言 有時出現的線上bug在測試環境死活都不能復現,靠review代碼猜測bug出現的原因,然後盲改代碼直接線上上測試明顯不靠譜。這時我們就需要在生產環境中debug代碼,快速找到bug的原因,然後將鍋丟出去。 生產環境的代碼一般都是關閉source map和經過混淆的,那麼如何進行debug代碼呢 ...
前言
有時出現的線上bug在測試環境死活都不能復現,靠review代碼猜測bug出現的原因,然後盲改代碼直接線上上測試明顯不靠譜。這時我們就需要在生產環境中debug代碼,快速找到bug的原因,然後將鍋丟出去。
生產環境的代碼一般都是關閉source map和經過混淆的,那麼如何進行debug代碼呢?我一般都是使用這兩種方式debug線上代碼:“通過console
找到源代碼打斷點”和“通過network
面板的Initiator
找到源代碼打斷點”。
通過console
找到源代碼打斷點
打開瀏覽器控制台的console
面板,在上面找到由bug導致拋出的報錯信息或者在代碼裡面通過console.log
打的日誌。然後點擊最右邊的文件名稱跳轉到具體的源碼位置,直接在代碼中打上斷點就可以debug代碼了。
如果點擊右邊的文件名後出現這種404報錯的情況。
could-not-load-content-for-webpack://***-(fetch-through-target-failed:-unsupported-url-scheme;-fallback:-http-error:-status-code-404,-net:: ERR_UNKNOWN_URL_SCHEME)
只需要點擊控制台右邊倒數第三個圖標setting(設置),將preferences(偏好設置)中的Enable JavaScript source maps(啟用 JavaScript 源代碼映射)取消勾選後再重新點console
最右邊的文件名稱即可。
這種方式很簡單就可以找到源代碼,但是有的bug是沒有報錯信息的,而且我們也不可能到處都給代碼加上console.log
,所以這種方式有一定的局限性。
通過network
面板的Initiator
找到源代碼打斷點
將滑鼠放到請求的Initiator
(啟動器)後,就會顯示當前請求完整的調用鏈中的方法和函數。假如請求是由A函數中發起的,B函數調用了A函數,C函數又調用了B函數。那麼這種情況中Initiator
就會按照順序依次將A、B、C函數都列出來。
瞭解了Initiator
的作用思路就清晰了,我們只需要找到離bug最近的一個介面請求,然後從調用鏈中找到我們需要的方法或者函數就可以了。
這時有的小伙伴又會說了,線上的代碼都是經過混淆的,原本代碼中的函數和變數經過混淆後已經都不是原本的名字了,那麼我們怎麼知道調用棧中哪個是我們想要找的函數呢?
確實函數和變數名稱經過混淆後已經變得面目全非了,但是對象中的方法和屬性名稱是不會被修改的,還是會保留原本的名字。比如我們有一個對象名字叫user,user中有個名叫dance的方法。經過混淆後user對象的名字可能已經變成了U,但是dance方法還是叫原本的名字,不會被修改。利用這一點我們可以在調用棧中找到我們熟悉的對象方法名稱就可以很快的定位到源代碼。
舉個例子,我們當前有個service/common.js
文件
import axios from "axios";
const urls = {
messageList: "http://127.0.0.1:3000/api/getMessageList",
};
const methods = {
getMessageList() {
return axios({
method: "get",
url: urls.messageList,
});
},
};
export default {
urls,
methods,
};
業務組件中這樣調用
import CommonService from "@/service/common.js";
async function initData() {
const res = await CommonService.methods.getMessageList();
const formatData: Array<Message> = handleFormatData(res.data.list);
messageList.value = formatData;
}
在Initiator
調用棧中就可以很容易的找到getMessageList
方法,並且我們知道getMessageList
方法是我們的initData
調用的。那麼在調用棧中getMessageList
的上一個就是我們想要找的源代碼位置,點擊文件名稱就可以跳轉到目標源代碼具體的位置。
如果跳轉到源代碼後代碼是被壓縮的狀態,點左下角的花括弧將代碼格式化。找到具體的定位後,經過比對其實混淆後的代碼和源代碼其實差別不是特別大,debug代碼還是很容易的。
這時有的小伙伴又會問了,假如我們出現bug的地方沒有介面請求怎麼辦呢?
這種情況也可以利用Initiator
調用棧找到對應的源代碼js文件,然後搜索你知道的屬性和方法名字,因為屬性和方法名稱在混淆的過程中是不會被重寫的。這樣也可以找到源代碼的位置。
總結
這篇文章主要介紹了兩種線上上debug源碼的方法。第一種方法是在控制台找到console
輸出,點擊console
右邊的文件名稱跳轉到源碼進行debug。第二種方式通過請求的Initiator
調用棧,找到源代碼中對應的方法,點擊文件名稱也可以跳轉到源代碼具體的位置。
如果我的文章對你有點幫助,歡迎關註公眾號:【歐陽碼農】,文章在公眾號首發。你的支持就是我創作的最大動力,感謝感謝!