5分鐘教會你如何在生產環境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調用棧,找到源代碼中對應的方法,點擊文件名稱也可以跳轉到源代碼具體的位置。

如果我的文章對你有點幫助,歡迎關注公衆號:【歐陽碼農】,文章在公衆號首發。你的支持就是我創作的最大動力,感謝感謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章