引入日誌點(Logpoints)和自動附加(auto-attach)功能
2018年7月12日 Kenneth Auchenberg, @auchenberg
在過去的幾個月裡,我們一直忙於改進 Visual Studio Code 中的除錯體驗。在這篇文章中,我將討論我們如何思考除錯、展示我們從使用者那裡聽到的反饋,並解釋我們為使 VS Code 中的除錯更輕鬆、更簡單而採取的步驟。
從 VS Code 誕生之初,我們就集成了除錯體驗,因為我們認為除錯應該是您編寫和編輯原始碼的地方(即您的編輯器)不可或缺的一部分。

VS Code 的除錯體驗由一個通用的偵錯程式 UI 提供支援,該 UI 透過除錯介面卡協議 (DAP) 與我們稱之為除錯介面卡 (DA) 的特定型別 VS Code 擴充套件進行通訊。DA 與真正的偵錯程式通訊,並在 DAP 與偵錯程式執行時特定的除錯協議或 API 之間進行轉換。
這意味著 VS Code 的核心與特定的偵錯程式完全解耦,並且這種架構允許 VS Code 除錯任何東西,只要有可用的除錯介面卡,如下圖所示

觀察和痛點
如今,有一大群滿意的開發者經常使用 VS Code 進行除錯,但是,作為我們使命的一部分,我們希望讓除錯更容易,併為更多的開發者所用。
為此,我們開始對話,以更好地瞭解 VS Code 中除錯的痛點,並瞭解為什麼有些開發者根本不使用我們的偵錯程式。
以下是我們的觀察結果
除錯配置難以正確設定
VS Code 是一個帶有通用偵錯程式的通用編輯器,它不針對特定的堆疊或執行時進行專業化。因此,我們無法提供一個適用於所有人的有主見的預設除錯配置。
這意味著 VS Code 要求您配置偵錯程式設定,並指定如何使用正確的引數等來啟動執行時。
我們認識到這可能很難正確設定,但我們看不到徹底消除所有人的除錯配置的方法。然而,我們確實相信除錯配置可以簡化,並且可以根據上下文減少到最低限度。
稍後我會回到這個問題。
啟動(launch)和附加(attach)配置之間的混淆
在 VS Code 中,我們有兩個核心除錯概念:啟動(Launch)和附加(Attach),它們處理兩種不同的工作流和開發者群體。根據您的工作流,瞭解哪種型別的配置適合您的專案可能會令人困惑。
如果您來自瀏覽器開發者工具背景,您不習慣“從工具啟動”的概念,因為您的瀏覽器例項已經開啟。當您開啟開發者工具時,您只是將開發者工具附加到您開啟的瀏覽器標籤頁。另一方面,如果您來自 Java 背景,讓您的編輯器為您啟動 Java 程序,並且您的編輯器自動將其偵錯程式附加到新啟動的程序是很正常的。
解釋啟動和附加之間區別的最佳方式是,將啟動配置視為在 VS Code 附加到應用程式之前如何以除錯模式啟動應用程式的“食譜”,而附加配置則是如何將 VS Code 的偵錯程式連線到已經執行的應用程式或程序的“食譜”。
啟動配置的價值在於,透過建立可重複並與您的專案和團隊共享的配置,它們提供了一種方法來減輕使用正確的除錯引數啟動應用程式的認知開銷。
然而,當我們與開發者討論他們如何啟動應用程式時,我們看到了一個模式並做出了一個重要的觀察
觀察:許多使用 VS Code 的開發者非常喜歡整合終端(Integrated Terminal),並依賴命令列工具來啟動他們的應用程式。對許多人來說,在終端中執行命令,然後從編輯器附加偵錯程式是一種更自然的工作流。這類似於瀏覽器啟動後開啟開發者工具。
這個觀察是關鍵,我們意識到許多使用者不想要一個完整的“神奇”啟動體驗在他們的編輯器中。他們希望將編輯器作為編輯和除錯原始碼的地方,並使用終端來啟動應用程式、執行構建指令碼等。這也是為什麼我們在 VS Code 中提供整合終端體驗的原因之一,因為我們相信一個好的功能 UI 應該與終端共存並良好整合。
許多開發者不使用斷點,因為他們在檢查狀態變化
在觀察開發者如何除錯他們的應用程式時,我們還看到了另一個有趣的模式:使用日誌記錄代替斷點。
用於除錯的日誌記錄並不是一個新概念,但觀察結果很重要
觀察:傳統的除錯工作流最關注於減慢執行速度以檢查程式邏輯,而日誌記錄工作流通常涉及檢查程式狀態及其在應用程式正常執行期間如何變化。這裡的基本觀察是,這兩種技術用於不同的除錯目的。
這個觀察結果對於 JavaScript 開發者尤其相關,他們主要處理管理狀態的複雜性,這可能解釋了為什麼大多數 JavaScript 開發者仍然喜歡在原始碼中新增 console.log 而不是使用指令碼偵錯程式。
自動附加到 Node 程序
在反思一些開發者如何使用整合終端來啟動他們的除錯會話時,我們看到了一個獨特的機會。透過利用我們在 VS Code 內部從您的編輯器和整合終端獲得的上下文資訊,我們可以檢測您的上下文並推斷您的除錯意圖,這可以為 Node.js 開發者提供更簡單的除錯體驗。
因此,在 VS Code 的三月迭代中,我們釋出了一個名為Node 自動附加(Auto Attach for Node)的新功能,它使 Node 偵錯程式能夠自動附加到從 VS Code 整合終端以除錯模式啟動的 Node.js 程序。
您可以透過在命令面板中執行 Debug: Toggle Auto Attach 命令來啟用自動附加,啟用後您也可以從狀態列切換自動附加。

此功能完全消除了任何除錯配置,因為我們將任何以 node --inspect 啟動的 Node.js 程序解釋為除錯意圖。當與整合終端結合使用時,它是一種更簡單的除錯體驗,允許開發者以自己的方式啟動應用程式,同時消除了除錯配置!🎉
NPM 指令碼和除錯
許多 Node.js 開發者依賴 npm 指令碼來啟動應用程式或開始除錯會話,我們在這方面也有一些好訊息:自動附加也適用於 npm 指令碼。如果您執行 npm run debug 並且 "debug" 指令碼是 "node --inspect" 或任何包含 --inspect 的其他命令,那麼自動附加將檢測到它並附加偵錯程式 🎉
我們還認識到一些開發者希望以更直觀的方式查詢和執行他們的 npm 指令碼,因此在 2018 年 4 月的迭代中,我們添加了一個新的 NPM 指令碼資源管理器,允許您直接從 UI 瀏覽和執行您的 NPM 指令碼。作為我們簡化除錯配置工作的一部分,我們還使得可以直接從資源管理器開始 Node.js 除錯,而無需建立除錯配置。
如果您有一個包含除錯引數(如 --inspect)的 npm 指令碼,我們將自動檢測到這一點,並提供一個啟動偵錯程式的除錯操作,如下圖所示

引入日誌點(Logpoints)
基於日誌記錄是一種重要的除錯技術的認識,我們看到了將狀態檢查新增到我們現有除錯體驗中的機會。在 VS Code 的三月迭代中,我們釋出了我們稱之為日誌點(Logpoints)的除錯功能的首次實現。
日誌點是一種斷點變體,它不會“中斷”到偵錯程式中,而是將訊息記錄到控制檯。

日誌點的概念並不新鮮,在過去幾年中,我們在諸如 Visual Studio、Edge DevTools 和 GDB 等工具中看到了這種概念的不同形式,名稱包括 Tracepoints 和 Logpoints。
為什麼以及何時使用日誌點?
日誌點基於這樣的觀察:在許多情況下,您不想停止應用程式特定部分的執行,而是想檢查狀態在應用程式生命週期中如何變化。
日誌點允許您在應用程式邏輯中“按需注入”日誌記錄語句,就像您在啟動應用程式之前添加了日誌記錄語句一樣。日誌點是在執行時注入的,不會保留在原始碼中,因此您無需提前計劃,可以在需要時注入日誌點。另一個好處是,您不必擔心在除錯完成後清理原始碼。
對於 JavaScript 開發者來說,這意味著您不必再擔心留下 console.logs –– 只需使用日誌點!更好的是,您可以結合使用 console.log 和日誌點。如果您在一個已經有 console.logs 的原始碼塊中插入一個日誌點,您將在除錯控制檯中看到兩種型別的日誌記錄語句。
雲環境中的日誌點
日誌點在雲環境中(或任何遠端環境中)特別有用,因為它們使您無需重新部署應用程式即可將日誌記錄注入到遠端環境中。同樣重要的是,您不會使用日誌點停止指令碼執行,因此您的使用者不會受到影響,這與在常規斷點處停止正在執行的應用程式不同。
您可以在此處閱讀有關如何在 Azure 上將日誌點用於 Node.js 的更多資訊。
支援的語言
自 VS Code 中首次釋出日誌點以來,我們看到 VS Code 除錯介面卡的採用率不斷增長,如今以下語言支援日誌點
- Node.js 偵錯程式
- Chrome 偵錯程式
- Firefox 偵錯程式
- Microsoft Edge 偵錯程式
- React Native 偵錯程式
- Python 偵錯程式
- Dart 偵錯程式
- Lua 偵錯程式
- Java 偵錯程式
- Mainframe 偵錯程式
VS Code 中的日誌點
如果您有興趣在您的 VS Code 除錯介面卡中新增日誌點支援,請檢視協議中的這些更改。您也可以檢視上述除錯介面卡,瞭解每個執行時如何選擇實現日誌點。
後續步驟
目前就這些,但我們還沒有完成。根據使用者反饋,在我們的七月迭代中,我們正在改進自動附加功能,以幫助提高可發現性(#53640)。
我們希望引入自動附加、NPM 指令碼資源管理器和日誌點能使使用 VS Code 進行除錯變得更加容易。一如既往,我們渴望聽到您的反饋,因此請透過 GitHub 或 Twitter 上的 @code 聯絡我們。
代表 VS Code 團隊:祝您編碼愉快!
/Kenneth Auchenberg - @auchenberg on Twitter