Chrome Devtools: Sources篇

相關篇章

Chrome Devtools: Elements篇css

概述

Sources面板用於資源檢索、代碼邏輯調試。html

演示前置

示例

其餘篇章有的是以掘金爲示例演示的,而掘金是服務端渲染(SSR),資源壓縮,不易演示。git

環境

  • Chrome瀏覽器
  • 版本 90.0.4430.93

操做釋義

  • 聚焦控制檯
  • 鼠標在控制檯範圍內點擊一下,使後續操做上下文綁定在控制檯中。

打開控制檯

ElementUI官網爲示例講述:
devtool.pnggithub

經過連接打開頁面,經過F12或鼠標右鍵【檢查】打開開發者工具控制檯。chrome

默認佈局

layouts.png

  1. 資源管理器面板segmentfault

    • 該面板下又細分不一樣的面板,默認展現的是Page面板
    • Page面板默認以域名分類,列出站點依賴的全部資源
  2. 代碼編輯面板跨域

    • 在資源管理器面板中選中一個文件後,該文件的內容展現在該面板
  3. 代碼Debugger面板瀏覽器

    • 操做斷點
    • 查看斷點上下文

Sources面板

該面板下的功能牢牢依賴着資源管理面板、代碼編輯面板、調試面板。網絡

只不過細分到下層面板管理不一樣的資源:dom

  • Page面板

    • 管理遠程站點資源
  • Filesystem面板

    • 將Sources面板當IDE(代碼編輯器),管理本地站點資源
  • Snippets面板

    • 管理瀏覽器持久化代碼資源

咱們以Page面板爲主體講述,其它小面板(Filesystem、Snippets)一帶而過。

Page面板

面板佈局1:資源管理器

默認佈局的1位置即Page面板的所有內容,該面板列出了當前站點頁面執行的全部資源,咱們能夠經過該面板獲取如下站點信息:

  • 技術棧:

    • 能夠從資源的關鍵代碼查看
  • 相關資源:

    • 從資源列表中一眼能看出頁面加載的資源類型
    • 當前頁面執行的自定義腳本,好比Snippets面板下定義的...
  • 依賴域:

    • 從資源分類上,依賴資源所在域一目瞭然
  • 瀏覽器擴展程序

    • 當前頁面加載的瀏覽器擴展程序
    • 爲了乾淨的調試環境,排除擴展程序的干擾,因此,通常選用無痕模式調試

      • 前提:沒有開啓擴展程序無痕模式下可用

面板佈局2:代碼編輯面板

在Page面板中點擊任意資源,便可在默認佈局2的編輯面板中看到資源詳情。
imageDetails.png
上圖點擊了圖片資源,能夠看到該圖片是一張二維碼。
css-runtime.gif
上圖點擊了CSS資源,在默認佈局2位置的編輯面板中,能夠點擊左下角的 {} 按鈕,進行代碼美化 —— 根據當前CSS資源的大小,美化所須要的時間不一樣。

若資源太大,瀏覽器可能會由於CPU佔用太高卡死。

這裏咱們作了一個試驗,檢索到頂部菜單的選擇器,進行樣式更新,能夠實時地在頁面上看到展現效果,甚至不須要保存。

然而,在這裏修改的代碼只是保存在內存中,刷新頁面代碼就還原了。

JS資源調試

這裏,咱們將Javascript資源單獨講述,由於在Devtools中JS資源調試的複雜度較高。

調試JS的場景

  • 在編寫代碼過程當中,查看未知參數的結構;
  • 在編寫、Bug修復過程當中,運行結果與邏輯設計不符時,代碼邏輯梳理;

調試JS的步驟

以修復Bug爲例:

  1. 找出Bug復現的規律
  2. 熟悉代碼的前提下,由規律出發,推斷Bug復現的範圍
  3. 在不一樣的範圍打(條件)斷點
  4. Step by Step的調試斷點
  5. 根據調試的結果,不斷的縮小Bug範圍
  6. 縮小至找到肯定的問題
  7. 針對找到的問題,提出解決方案
  8. 評估解決方案,選擇合適的方案修復

Note:針對網絡請求,斷點時間過長會形成請求超時。

斷點 vs. 日誌

說到調試代碼,經常使用的方式有兩種:斷點、日誌;

斷點Debugger 日誌Console
中斷代碼的執行 不中斷代碼的執行
查看中斷代碼那一時刻的上下文信息 查看代碼執行結束的上下文信息
非侵入式 侵入式,將日誌代碼寫入業務代碼中
查看代碼中斷時刻全部的執行上下文信息 只能查看指定的打印信息
時效性:此時此刻的值 代碼執行結束時指定信息的值,除非深拷貝

示例

在代碼編輯面板中,只有針對Javascript的斷點才能攔截執行成功,而針對DOM的斷點,須要在Elements面板添加:DOM的操做,詳情參見Elements篇。

下述以Chrome瀏覽器提供的官方調試代碼爲例:
debug.gif

打開控制檯,從Panel面板中能夠看到當前頁面只有兩個資源:HTML頁面及相關的JavaScript。
其它的是我安裝的Chrome擴展(沒有使用無痕模式)。

從get-started.html中咱們能夠看到相關的HTML結構、Style樣式及引入的JavaScript代碼

頁面邏輯

輸入Number一、Number2,點擊按鈕得到計算結果。

指望結果

計算獲取Number一、Number2兩個數字的和:1 + 1 = 2

實際結果

獲取到Number一、Number2字符串的拼接:1 + 1 = 11
1+1.png

復現率

100%,說明是邏輯錯誤,而不是代碼邏輯對某種邊界沒有覆蓋的機率問題。

代碼鎖定Bug範圍(嫌疑犯)
function updateLabel() {
  var addend1 = getNumber1();
  var addend2 = getNumber2();
  var sum = addend1 + addend2;
  label.textContent = addend1 + ' + ' + addend2 + ' = ' + sum;
}

由代碼 label.textContent = addend1 + ' + ' + addend2 + ' = ' + sum; 1 + 1 = 11 的顯示結果猜想,addend1addend2看似沒有問題,而sum看似有問題,那咱們就在sum計算的地方打斷點。

斷點調試

debugger.gif

在資源管理器中點擊html引入的Javascript文件,找到相關代碼,在行號位置點擊一下,即添加斷點,再次點擊同一行號,取消斷點。

點擊按鈕,觸發函數調用,此時,咱們能夠看到當前執行上下文中的全部信息,如addend1addend2的值,偷偷的執行F9(Step),能夠看到sum的結果。

診斷

從當前執行上下文能夠看到addend1addend2的值是字符串類型,而字符串作加法就是字符串的拼接,因此,結果沒問題!!!

是的,運算結果沒問題,那爲何不是咱們指望的結果呢?

由於咱們指望的是數字類型相加!!!

測試

聚焦控制檯,經過ESC按鍵能夠在當前面板開啓/隱藏Console面板,在控制檯的最下方。
test.png
藉助斷點將做用域限制在函數updateLabel內,經過Console面板驗證本身的猜測,此時,Console面板能夠訪問函數updateLabel的變量。

解決方案

solution.gif
那咱們只要將addend1addend2的值轉換爲數字便可。

方案有不少種:

  • parseInt()
  • parseFloat()
  • Number()
  • 1 * '1'
    ...

這裏,我直接在代碼編輯器面板中改動了getNumber1getNumber2的方法,另其返回數字類型的數據。

保存之後,點擊按鈕,能夠看到指望的結果。
expect.png
經過右上角按鈕,切換斷點的激活狀態,激活是深藍色,取消激活是有透明度的藍色。
取消激活狀態下,斷點不會攔截代碼的執行。

在取消激活的狀態下,能夠嘗試輸入不一樣的值,檢測邏輯的正確性。

簡單的調試示例到此結束。

CSS、JavaScript調試對比

JavaScript調試 CSS調試
須要保存 無需保存
須要手動執行調用,不會自動執行 自動執行,實時效果
可斷點攔截執行 斷點無效

斷點分類

上述調試Javascript的前提是要熟悉代碼,比較適用於在本身編寫的程序中調試。

若遇到其它的場景,如第三方庫調試,則須要根據相應的場景,選擇合適的斷點組合使用。

斷點類型 應用場景
代碼行斷點 大致/清晰知道調試範圍時使用
代碼行條件斷點 大致/清晰知道調試範圍時,且只調試某指定條件分支下使用
代碼行日誌斷點 非代碼侵入式的打印日誌
DOM斷點 調試指定DOM的改變、移除或子節點的變更,詳見Elements篇
XHR斷點 調試URL包含指定字符串的請求
事件監聽斷點 調試指定元素事件觸發邏輯時使用事件委託時使用比較麻煩推薦配合黑盒 + 無痕模式使用
錯誤斷點 調試錯誤捕獲時使用通常只用於調試未捕獲的錯誤

代碼行斷點

經過問題復現能推測出明確的調試代碼範圍時使用。
lineBreakpoint.gif
在代碼編輯面板的行號上右鍵或者直接點擊該行號,便可添加代碼行斷點。

代碼行條件斷點

在有中介統籌分配處理邏輯或條件分支時使用,排除其它邏輯的干擾,聚焦關注點。

conditionalBreakpoint.gif
由上圖可知,在代碼編輯面板的行號上右鍵,選擇Add Conditional Breakpoint...,便可添加代碼行條件斷點。

添加條件斷點時,若是條件爲true時,攔截代碼執行,條件爲false時,不會攔截。

在輸入框至少有一個爲空時,斷點有效,輸入框全不爲空時,斷點無效。

代碼行日誌斷點

無需侵入源代碼,實現非侵入式的日誌打印
logBreakpoint.gif
如上圖,輸入的格式是console.log函數的參數形式。

logtable.gif

如上圖,能夠顯式地使用console對象的其它方法打印日誌

DOM斷點

詳情參見Elements篇

domBreakpoint.gif

XHR斷點

xhrBreakpoint.gif
隨手找個請求,添加到XHR斷點,重載頁面,在請求send的時候,會攔截代碼邏輯,能夠查看相關的請求參數。

事件監聽斷點Event Listener Breakpoints

若對代碼不熟悉或在大長篇代碼邏輯中,只是知道點擊觸發業務處理邏輯時,能夠考慮事件監聽器斷點。

然而,在複雜的事件委託中,是一個噩夢。
Note:無痕模式下使用,瀏覽器擴展程序會產生干擾。

eventBreakpoint.gif

錯誤斷點

開啓錯誤斷點,默認會攔截未處理的錯誤邏輯。

若選擇Pause on caught exceptions,則捕獲的錯誤邏輯也會被攔截。

errorBreakpoint.gif

黑盒(Ignore list)

黑盒(舊版叫黑盒,新版瀏覽器更名爲忽略列表)是一小功能,單獨拉出來說是由於不適合和其它分類合併。

使用該功能能夠聚焦關注點,排除非核心或可信任代碼的干擾。

blackbox.gif

由於示例是一個很簡單地例子,這裏藉助Event Listener Breakpoints講述該功能地使用。

在Click事件上添加斷點,點擊Add Number1 and Number2按鈕,會在函數onClick地首行進行執行攔截,OK!

重載頁面,在代碼編輯面板打開可信任的代碼,右鍵添加Add script to ignore list,再次點擊Add Number1 and Number2按鈕,會發現代碼邏輯徹底執行結束,沒有攔截。

上述場景對比,咱們能夠意識到,黑盒幫助咱們聚焦相關邏輯代碼,跳過一些可信任(認爲不會出現Bug)的庫,如:jQuery?在一步步調試時,不會進入jQuery庫調試,聚焦咱們本身的邏輯。

代碼覆蓋率

能夠幫助咱們查找無效(Never)代碼。

coverage.gif

經過代碼編輯面板右下角的Coverage,咱們能夠查看代碼的覆蓋率。

如上圖,頁面初始化執行時,代碼未覆蓋率爲41.9%,即有41.9%的代碼在頁面初始化時未執行。

點擊Add Number1 and Number2按鈕,執行了輸入校驗相關的代碼邏輯,代碼未覆蓋率爲17.3%,即仍有17.3%的代碼未執行。

輸入輸入,點擊Add Number1 and Number2按鈕,執行了計算相關的代碼邏輯,代碼未覆蓋率爲0%,即代碼邏輯所有執行。

某種程度上能夠幫助咱們查找Never無效代碼。

面板佈局3:調試面板

單步執行

在調試代碼的過程當中,咱們須要控制代碼的執行:
steps.gif

如上圖,添加三個斷點,追加一個日誌。

觸發事件,點擊Resume script execution,會恢復代碼的執行,直至遇到下一個斷點。

若在攔截時,長按Resume script execution,選擇下拉按鈕的第一項,會跳事後續的斷點,將代碼執行完整,能夠看到日誌執行了一次。

若在攔截時,長按Resume script execution,選擇下拉按鈕的第二項,會在攔截處強制中止後續代碼執行,能夠看到後續邏輯中的日誌沒有執行。

重載頁面,使頁面恢復到初始狀態

resume.gif

調試面板最上排的工具控制斷點攔截時代碼的執行,Resume按鈕恢復代碼的執行,直至遇到下一個斷點。

若斷點所在代碼行的表達式是一個函數,step over按鈕會跳過函數的內部執行,如圖第15行(15L),下一步直接執行到了16L。

若斷點所在代碼行的表達式是一個函數,step into按鈕會深刻函數的內部執行,如圖第15行(15L),下一步進入了函數內部,執行到了22L。

執行到了22L後,若不想再調試該函數inputsAreEmpty,能夠經過step out跳出函數的執行,以下圖,下一步直接跳出當前函數的執行,執行到16L。

stepinto.gif

思考:

  • 若在22L,點擊了Step into按鈕,下一步會執行到哪?
  • 若在22L,點擊了Step through按鈕,下一步會執行到哪?

step.gif

最後看一下step按鈕,step按鈕是實名的老實人,遇山登山,遇海潛海,邏輯中的每一步都會走到,碰見函數就會深刻函數代碼執行每一步。

若邏輯中一個函數都沒有,step overstep intostep outstep的行爲和step保持一致。

禁用(Deactivate)、停用(disable)斷點

看下圖,分別執行了禁用、停用,看明白了麼?

deactivate.gif

上圖,加入了兩種類型的斷點,第一次正常執行,三個斷點都會執行的到。

第二次禁用了斷點,點擊Add Number1 and Number2,代碼執行完畢,斷點都沒有攔截。

第三次激活斷點(還原禁用),停用了斷點,點擊Add Number1 and Number2,代碼攔截在了Click事件處理邏輯的首行,後續斷點並無攔截。

迷糊了?

綜述:
停用是有做用域的,停用的只是代碼行斷點,其它類型的斷點並無停用。而禁用是所有類型的斷點都不會觸發。

監聽

重載頁面,移除全部的斷點。

watch.png

能夠增長表達式在Watch中,監聽執行各時間點的值。

函數調用的監聽會影響代碼邏輯的執行,如上圖中的 inputsAreEmpty()做爲Watch表達式,Watch在須要更新展現的時候(時機:代碼執行到表達式所在所用域),Chrome會自動調用該函數來獲取函數最新返回值。

若是在 inputsAreEmpty() 的函數邏輯中添加斷點,就會無限循環。

  • inputsAreEmpty() 代碼行處添加代碼行斷點,函數體會執行三次

    • 第一次,到達做用域時的初始值
    • 第二次inputsAreEmpty() 自己執行
    • 第三次 inputsAreEmpty()執行後,更新Watch表達式的值
    • 由於inputsAreEmpty() 函數體內無斷點,更新Watch表達式後,再也沒有其它時機更新表達式
  • inputsAreEmpty()函數體內添加代碼行斷點,函數體無限執行

    • 第一次 inputsAreEmpty()在執行做用域初始化
    • 第二次執行inputsAreEmpty()
    • 第三次執行 inputsAreEmpty() 後,更新Watch
    • 第四次更新Watch執行inputsAreEmpty()
    • 第五次執行inputsAreEmpty()後,更新Watch
    • 第六次...

因此,不推薦在Watch表達式中添加函數調用

做用域

scope.gif

在攔截代碼執行時,咱們能夠在調試面板的Scope章節看到當前做用域Local的變量,如上圖中的this。

繼續執行代碼到return 語句,能夠在當前做用域Local看到返回值Return Value

雙擊做用域中的值,能夠改變當前的值。

Global做用域能夠看到全局做用域的變量、方法。

global.gif

默認狀態下,Console面板只能訪問到全局的變量、函數,而在斷點攔截時,Console面板能夠訪問到當前做用域下的方法、變量。

調用棧

調用棧Call Stack,能夠看到當前執行函數的來源,幫助咱們溯源。

callstack.gif

在當前執行函數上右鍵,點擊 restart frame,可讓當前函數的邏輯從新執行,在大塊代碼段調試中使用較爲便利,僅限於斷點執行到的函數,已經走過的函數無效。

Filesytem面板

瀏覽器即代碼編輯器

filesystem.gif

如上圖,在本地啓動服務打開某靜態頁面,在Sources面板下的Filesystem面板添加靜態項目到workspaces。

經過Elements面板定位錨點到某DOM節點,在Styles面板直接調試樣式,重載頁面後,該樣式依舊有效。

經過查看樣式源碼,能夠發現Styles面板中調試的樣式已經保存到磁盤覆蓋原有的樣式。

適用場景

  • 靜態頁面的CSS、JavaScript

    • 上圖咱們能夠看到Filesystem中的一些文件的文件名有綠色小點

      • 綠點代表瀏覽器打開的該文件已經與本地磁盤創建鏈接
      • 在瀏覽器調試修改文件能夠直接映射到本地磁盤
  • 靜態頁面的HTML經過Elements面板右鍵 eidt HTML 沒法保存磁盤

    • Elements面板映射的是DOM Tree
    • DOM Tree的產生受 HTML、CSS(content樣式屬性)、JavaScript動態處理的影響,因此,瀏覽器沒法將DOM Tree的改變映射到對應的位置

【推薦】在結構、展示、動效(HTML、CSS、JavaScript)分離的靜態頁面項目中快速調試使用。

無效場景

  • 使用構建工具打包的項目

    • 即便使用sourceMap,複雜的文件映射關係使得瀏覽器和本地磁盤創建薄弱的鏈接
    • 鏈接不可靠

Snippets面板

Snippets面板爲咱們提供跨標籤、跨域名的Javascript測試性功能。

snippet.gif

上圖附了一段檢測瀏覽器類型的Javascript腳本, Ctrl + S 保存後,能夠打開其它頁籤,在Snippets面板中仍然能看到該腳本。

點擊右下角的執行按鈕或經過快捷鍵 Ctrl + Enter 執行這段腳本,能夠在下方的Control面板看到執行打印出來的日誌。

Snippets Console
跨標籤頁可用 當前標籤頁可用
永久保存,除非手動刪除 頁面重載後清除
相關文章
相關標籤/搜索