$0 和 __vue__ $0 是指當滑鼠點擊 Element 面板的某個 dom 元素後,console 里 $0 變數會自動指向該 dom 元素對象 __vue__ 是指 vue 框架會往 vue 組件 $mount 掛載的 dom 元素對象上添加一個 __vue__ 變數來指向當前 vue 組 ...
$0 和 __vue__
$0 是指當滑鼠點擊 Element 面板的某個 dom 元素後,console 里 $0 變數會自動指向該 dom 元素對象
__vue__ 是指 vue 框架會往 vue 組件 $mount 掛載的 dom 元素對象上添加一個 __vue__
變數來指向當前 vue 組件
這意味我們可以直接在 console 面板里拿到任意 vue 組件實例對象:
- 可以查看對象內部任意屬性
- 也可以直接操作對象內部的屬性來達到預期的調試效果
- 甚至可以用來查看三方庫的 api,比如 element-ui 的某個組件內部的 api
或許你會疑問,這不是安裝 chrome 插件(vue devtools)就可以搞定的事嗎,插件還是個可視化界面操作,更直觀便捷
沒錯!插件當然更方便,但沒準插件內部實現原理就是這樣的呢,掌握這個技巧,也可以在一些插件無法覆蓋的場景下來調試頁面,比如:
- 生產環境的頁面
- 內網部署且無法代理到本地的頁面
- 非 chrome 瀏覽器
- 等等
舉一反三:
- 很多開源庫框架其實都會往綁定的 dom 或者 window 上掛載一些變數上去,善於在 console 利用這些變數,可以方便我們進行很多非本地開發場景下的調試
- 我們日常封裝一些複雜業務、複雜組件時,也可以參考這種思路,給自己開一個非本地開發場景下的調試入口,但註意別記憶體泄漏了
- window 上掛實例對象變數容易導致記憶體泄漏,所以建議掛一些全局作用域的對象;實例對象儘量掛與他生命周期綁定的 dom 對象
介面數據搜索定位
網路面板支持多個維度的搜索功能:
- 根據內容關鍵詞定位介面
- 常用於看見界面某個文案或者只知道某個關鍵詞,但想定位它是哪個介面返回時的場景
- 在介面返回的內容里定位關鍵詞
- 根據 url 過濾介面
源碼定位
jquery 時代的網頁源碼直接原原本本在瀏覽器上,調試和閱讀都非常方便;
前端工程化後,混淆和壓縮已經是標配,當出現生產故障時,首先考慮的應該是本地復現或者是將生成環境頁面代理至本地的思路來解決;
但總會有某些場景,由於各種受限,只剩下瀏覽器直接操作的手段,因此,掌握一些源碼定位和調試的方式技巧還是有必要的
全局搜索
字元串、對象屬性欄位名這些不會被混淆,可以藉助這類場景的關鍵詞來搜索定位源碼位置
通常界面也是第一看到的東西,儘量找個界面上看著不像通用類的文案全局搜索下,基本都能定位到對應組件源碼
也可以審查元素,在 Element 面板里找到對應 dom 上比較唯一的 class 或 id 等來全局搜索
介面調用棧
介面也是邏輯分析的入口點之一,比如找到某個頁面呈現數據的請求介面,跟著調用棧走下去基本能梳理界面從拿到數據到呈現做了什麼事
但要註意過濾掉三方庫(如 axios, vue 等)對介面的封裝,找到真實屬於邏輯源碼的調用棧
console 面板的函數源碼跳轉
console 面板上的 log 日誌,或者通過 log 輸出一個函數,都支持點擊跳轉到對應源碼位置
藉助 $0 和 __vue__
變數,找到對應組件的某個方法入口,通過 log 輸出方法再跳轉至源碼位置,就能針對性的梳理某個邏輯源碼
事件監聽事件跳轉
對於某些按鈕等組件的點擊之類的事件,可以直接通過審查元素的 Element 面板的 EventListeners(事件監聽器)這邊查看到該按鈕各類事件的監聽器
過濾掉三方庫的統一事件監聽器,找到自己邏輯源碼的事件監聽器入口,也能針對性梳理該事件處理邏輯源碼
源碼調試
斷點
代碼裡加入 debugger 可以觸發斷點,但前提是本地開發調試模式
也可以直接瀏覽器上操作斷點,除了常規的直接點擊源碼斷點之外,也可以使用一些具體場景的斷點,比如定時器觸發時進入斷點、非同步請求響應時斷點,DOM 變更時斷點等等
overrides(覆蓋)
如果想在瀏覽器上修改源碼並生效的話,需要使用到 overrides(覆蓋|替換)功能,如上圖
先在 Source(源代碼/來源) 面板啟用 overrides(替換) 功能,然後找到要編輯的源碼文件,右鍵,點擊替換內容(Save for override)
接下去就可以直接瀏覽器上修改源碼,刷新後會載入這份修改後的代碼文件
當你發現網路面板有個感汗號警告時,就意味著你啟用了本地替換的功能,指定的源碼文件不會從網路上載入,而是載入本地臨時替換修改過的文件
這樣就可以達到直接在源碼調試的效果
實操場景說明
以上是個人日常比較常用的一些操作,每個技巧都不是割裂開的,經常是組合交叉使用
比如某生產環境來了個故障,本地無法復現,無法代理,還是個內網,只能遠程客戶設備直接在瀏覽器界面上調試定位
首先,我們要定位到大概源碼,然後分析、斷點、調試
怎麼定位源碼呢:
- 字元串是不會被混淆的,所以可以全局搜索方式來嘗試
- 如果匹配點太多,那也可以先定位到某個關鍵介面,然後根據介面定位到源碼
- 如果還是沒有定位到,對象的屬性是不會被混淆的,所以也可以通過
$0 和 __vue__
來根據某個 vue 組件的方法來定位源碼
定位到源碼後,斷點還分析不出問題時,就可以繼續利用 overrides
覆蓋功能來直接修改瀏覽器源碼進行調試