由於圖片和格式解析問題,可前往 閲讀原文
在現代前端與全棧開發的日常工作中,代碼調試是不可或缺的一環,而一款優秀的調試工具能夠顯著提升開發效率,減少問題定位的時間成本。Visual Studio Code(簡稱 VSCode)作為一款備受開發者喜愛的輕量化編輯器,不僅提供了豐富的插件生態和高效的代碼編輯體驗,更以其強大的調試功能成為開發者工作流中不可或缺的一部分
無論是調試 Node.js 後端代碼、前端瀏覽器代碼,還是更復雜的容器化微服務系統,VSCode 都提供了靈活的調試支持。而這種強大的調試能力,並不僅限於簡單地設置斷點或查看變量,更體現在其對多種語言、運行時環境的無縫支持以及對調試配置的高度自定義能力上。通過掌握 VSCode 調試工具,開發者不僅能夠輕鬆解決代碼問題,還可以培養更系統化的調試思維,提升整體開發質量
在接下來的內容中,我們將圍繞 VSCode 的調試功能展開深入剖析,從基本的斷點設置到複雜的調試場景,帶您全面解鎖 VSCode 調試的潛能,助力高效開發
調試界面
和大多數調試器的功能模塊界面基本上一致,包含:執行器、變量、執行棧、調試終端等等,比較簡單這裏就不多做介紹了;如果你對調試面板的操作步驟還不是很熟悉,可以看我的往期文章或者「vscode調試基本介紹」
調試分類
vscode支持多種形式的調試,從調試配置的複雜度來劃分,可以分兩大類:簡單、複雜;
簡單的調試可以快速的進入調試,無需關心過多的外在因素,通常這類的調試偏向於簡單、無需相關工具輔助之類的項目,如:簡單的原生js工程、NodeJS工程等等。簡單的調試這裏會介紹:auto attach、Javascript Debug Terminal
而相對複雜的工程就不能使用這種模式了,當然也要具體的場景。面對複雜的場景,vscode提供了launch.json配置文件來定製化debug的功能,可以很方便的適配到不同的應用場景
Auto attach
auto attach顧名思義就是自動鏈接的意思,也就是當程序啓動debug模式時,vscode就會自動連接到目標debug,然後根據vscode提供的調試UI進行調試
若要使用此功能需要在vscode中開啓配置,cmd+shift+p 輸入 >Debug: Toggle Auto Attach 後回車,支持多種形式的選項,大體分為:
- always:當程序啓動debug時總是自動連接上
- flag:當監聽到
--inspect或--inspect-brk時才自動連接 - disabled:禁止
注意:當選擇相關配置後,可能需要重啓IDE
下圖中小編啓動的是flag模式,在IDE底部欄會有對應的顯示,然後在終端輸入 node --inspect script 啓動程序,此時IDE就會自動連接上目標debug
可能心細得同學就已經發現了,當使用調試模式運行程序後,調試器會啓動一個ws服務,為什麼會有這個東西❓也有同學會疑問為啥vscode就能自動鏈接上目標debugger呢❓並且可以調試程序呢❓
現在讓我們打開chrome瀏覽器並輸入 chrome://inspect/#devices 打開調試TAB,會發現我們的目標程序,當點擊 inspect 後會打開一個 Dev Tool 並且也可以調試目標程序
通過Chrome鏈接基本上可以肯定的是,調試UI會通過ws進行調試數據的傳輸,而vscode之所以會自動鏈接一定做了相關事件監聽或者觸發。後面部分我們會揭曉調試UI和目標Debugger之間的數據傳輸原理
如果沒看到目標程序,需要將啓動node程序後的ws服務ip和端口配置到 Discover network targets 即可
Javascript Debug Terminal
如果説上面的auto attach調試方式已經足夠簡單,那麼Javascript Debug Terminal可以説是更加傻瓜式調試,簡直有手都會系列‼️讓我們來看看怎麼個簡單法
只需要打開Javascript Debug Terminal終端,然後像往常一樣啓動程序一樣:
- 打開對應的終端
- 啓動程序
vscode對於調試的友好性已經考慮到非常周全了
到這裏就將簡單形式的調試已經介紹完畢了,確實很簡單,很時候一些需要快速、簡單的調試場景,當然,實際場景中往往程序都是以複雜的工程出現的,那麼這種簡單的調試模式可能就不適用了,接下來看看vscode是如何支持複雜性工程的調試的
Debug Configuration
在 Visual Studio Code(VSCode)中,Debug Configuration(調試配置)是調試功能的核心。它允許開發者根據項目需求自定義調試環境、參數和行為。調試配置通常存儲在項目的 .vscode/launch.json 文件中,通過 JSON 格式定義調試任務
創建launch.json文件有多種方式,支持手動、可視化等等,你可以打開Debug擴展,然後根據提示創建對應的文件:
在選擇debugger時選擇我們熟悉的node、chrome都行,最終都是可以通過配置文件調整
一個典型的 launch.json 文件由以下部分組成:
{
"version": "0.2.0", // 配置文件的版本號,固定為 0.2.0
"configurations": [
// 調試任務列表
{
"type": "node", // 調試類型,例如 "node", "python", "chrome"
"request": "launch", // 調試請求類型:"launch"(啓動程序)或 "attach"(附加到運行的進程)
"name": "測試NodeJS", // 調試任務的名稱,顯示在調試面板中
"program": "${workspaceFolder}/index.js", // 主程序文件路徑
"cwd": "${workspaceFolder}", // 當前工作目錄
"env": {
// 環境變量
"NODE_ENV": "development"
},
"args": ["--verbose"], // 啓動參數
"port": 9229 // 調試所需的端口(僅部分配置需要)
}
]
}
配置文件模式最大的區別就是type,總體來説它把調試劃分成兩大分類:
- launch:以調試模式啓動程序
- attach:附加到正在運行的Debuger進程
創建配置
在launch.json中可以快速創建對應類型的配置,vscode給了對應的配置
輸入花括號後會有對應的提示
也點擊右下角的Add COnfiguration按鈕
Task
在正式介紹調試配置文件前,先來介紹下Task;這又是什麼❓在 VSCode 中,Task 是一個功能強大的任務管理工具,用於執行各種自動化操作,例如運行構建工具、執行腳本、啓動開發服務器、或調用外部命令。通過配置 Task,可以將常用的命令集成到 VSCode 中,大幅提升開發效率
説明了就是可以幫助我們執行一些自動化的任務,如:腳本、npm等等,結合調試就可以做一些自動化的東西。比如,我們需要調試一個目標程序前,可能需要將其編譯才行,那麼就可以將編譯的任務交給Task,調試配置文件也確實提供了對應的屬性:postLaunchTask、preLaunchTask
{
// postLaunchTask ...
"preLaunchTask": "tsc: build" // 定義的 task 的 label 值
}
那麼如何配置task呢,可以通過輸入對應命令生成:.vscode/tasks.json
可以根據具體的場景調試配置:
{
"version": "2.0.0",
"tasks": [
{
"type": "typescript",
"tsconfig": "ts-examples/tsconfig.json",
"problemMatcher": [
"$tsc"
],
"group": "build",
"label": "tsc: build"
}
]
}
接下來我們來看兩大調試方式吧
attach
attach調試比較簡單,就是鏈接到對應的目標Debugger調試程序進程上,以下是一個attach例子,通過attach方式鏈接到9229端口目標調試器上
{
"name": "Attach NodeJS Break Debugger",
"port": 9229,
"address": "localhost",
"request": "attach",
"skipFiles": [
"<node_internals>/**"
],
"type": "node"
}
當我們在終端以調試的方式啓動程序後,在調試插件界面,啓動這個調試後就會自動鏈接上目標調試器:
這個其實和前面介紹的auto attach 以及用 Chrome 進行調試道理是一樣的
此模式下也包含很多相關的屬性配置,這裏簡單列舉幾個:
- outFiles:源文件輸出的目標文件,一般對於編譯文件,vscode會自動匹配來做sourcemap映射
- resolveSourceMapLocations:用於指定調試器在解析源映射(Source Maps)時可以加載的文件路徑或 URL
- continueOnAttach:用於控制調試器在附加到正在運行的進程時,是否自動繼續執行程序,如:
--inspect-brk模式調試時的場景
launch
如果説到這裏還覺得配置文件方式的調試也比較的話,那麼launch模式調試就會多樣化了,我覺得它可以代表配置文件調試的核心,此種模式功能有很多
launch顧名思義就是啓動的意思,的確它通過配置文件告訴vscode以debug形式啓動目標程序,然後自動鏈接到調試UI上,這種模式自動化完成了啓動與連接的過程
launch支持多種啓動程序的方式,下面是常用形式:
- url:通常是啓動瀏覽器打開對應的地址
- program:指定啓動的應用程序文件
- runtimeExecutable:通過執行器執行,如:npm、yarn、pnpm等等,這些執行器必須能正常使用
url
此種方式會直接打開設置的url,vscode內部會根據內置的策略將頁面通過sourcemap與源碼關聯起來,如果程序需要編譯但沒有提供對應的sourcemap,將無法進行調試,此時打的斷點都是灰色的
{
"name": "Launch Chrome",
"request": "launch",
"type": "chrome",
"url": "http://localhost:8082",
"webRoot": "${workspaceFolder}"
}
請注意:以上url服務需要提前運,這裏使用 http-server 指定 8082 端口運行
program
program則指定vscode要運行的程序文件,比如運行node程序main.js
{
"type": "node",
"request": "launch",
"name": "Test Launch Debugger",
"args": ["author=ihengshuai"],
"program": "${workspaceFolder}/node/index.js",
"env": { "website": "https://blog.usword.cn" }
}
此種形式通常可以搭配args、env提供相關的參數變量等等
同樣的如果程序也需要轉義,請提供相關的sourcemap
runtimeExecutable
runtimeExecutable 用於指定調試程序的運行時可執行文件,該字段通常用於指定運行調試目標所需的特定運行環境,例如 Node.js 的可執行文件、Python 解釋器或其他自定義的可執行程序
{
"type": "node",
"request": "launch",
"name": "Test Launch Debugger",
"skipFiles": [
"<node_internals>/**"
],
"cwd": "${workspaceFolder}/node",
"args": ["author=ihengshuai"],
"runtimeExecutable": "npm", // 使用npm啓動
"runtimeArgs": ["run", "debug", "github=ihengshuai"], // npm 後面的參數, npm run debug
"env": { "website": "https://blog.usword.cn" }
}
此種方式的效果圖和以上基本一致
重要的屬性
launch方式調試有多種屬性可以選擇,這裏我們列舉幾個
- args:用來給目標程序傳遞對應的變量
- cwd:指定啓動目標程序的基本路徑,一般都會在項目的根目錄,如果對於多倉庫項目,可以你可以指定對應的文件路徑
- runtimeArgs:傳給
runtimeExecutable的參數,比如對應的執行腳本命令:build、lint等等 - env和envFile:環境變量,和
.env配置文件定義類似 - console:啓動程序的終端,默認是debug終端,如果對於程序執行過程中一些特殊要求,你可以選擇vscode終端或者外部的終端,有
internalConsole、integratedTerminal、externalTerminal幾個配置
除了這些屬性配置外,可以很多其他的屬性選項,請結合不同的type提示選擇使用對應的屬性
設置sourcemap
對於大多數的真實場景來説,都會是基於各種打包器的比較複雜的大型工程,那麼生成的文件都會是經過壓縮或者含義後的內容,而調試則需要對應sourcemap的支持,這樣才能和源碼映射起來
配置文件提供了sourcemap相關的配置:
- sourceMaps:默認為true,啓用sourcemap
- outFiles:用於指定編譯後的文件路徑的位置,調試器會使用這些文件來加載 Source Map
- webRoot:用於指定 Web 應用的根目錄
- sourceMapPathOverrides:用於覆蓋和重映射源代碼路徑,當 Source Map 文件中記錄的路徑與實際文件路徑不一致時,通過此字段解決路徑匹配問題
- resolveSourceMapLocations:控制調試器加載 Source Map 文件的路徑範圍
比如我們基於webpack進行路徑映射的調整:
{
"sourceMapPathOverrides": {
"webpack:///./*": "${webRoot}/src"
},
}
注意:以上只是簡單的一個例子,請根據具體的項目場景設置
分組調試
vscode支持將多個調試分組,可以按組運行調試器
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch Chrome Browser",
"request": "launch",
// ...
},
{
"name": "Launch Node Server",
"type": "node",
// ...
},
],
"compounds": [ // 定義組
{
"name": "Run Debugger",
"configurations": ["Launch Chrome Browser", "Launch Node Server"]
}
]
}
到這裏基本上將vscode的調試功能講完了,接下來我們來幾個真實的調試案例
調試案例
調試Vue源碼
配置好調試,終端啓動對應的服務腳本:
啓動debug會打開對應的瀏覽器,這裏我們點進對應的文件目錄和文件:
在對應的源碼文件中打斷點:
調試NodeJS
{
"name": "Test Express App",
"request": "launch",
"runtimeArgs": [
"run-script",
"express-app"
],
"runtimeExecutable": "npm",
"skipFiles": [
"<node_internals>/**"
],
"type": "node"
}
調試NestJS
{
"version": "0.2.0",
"configurations": [
{
"name": "Test NestJS",
"request": "launch",
"runtimeArgs": [
"run-script",
"start:dev"
],
"runtimeExecutable": "pnpm",
"skipFiles": [
"<node_internals>/**"
],
"type": "node"
}
]
}
調試Typescript
由於目標程序是ts,所以需要sourcemap的支持,上面我們講了幾種方式配置
{
"name": "Launch Typescript",
"type": "node",
"request": "launch",
"skipFiles": [
"<node_internals>/**"
],
"program": "${workspaceFolder}/ts-examples/demo1.ts",
"outFiles": [
"${workspaceFolder}/ts-examples/dist/*.(m|c|)js",
"!**/node_modules/**"
],
}
調試SSR
ssr有服務端和前端,我們可以使用組合方式進行調試,頁面通過啓動瀏覽器的方式進行調試,node端通過腳本形式啓動服務,這樣就可以調試了
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch Chrome Browser",
"request": "launch",
"type": "chrome",
"url": "http://localhost:10011",
"webRoot": "${workspaceFolder}/client",
"sourceMaps": true,
},
{
"name": "Launch Node Server",
"type": "node",
"request": "launch",
"skipFiles": [
"<node_internals>/**"
],
"runtimeExecutable": "pnpm",
"runtimeArgs": ["dev"],
"sourceMapPathOverrides": {
"webpack:///./*": "${webRoot}/src"
},
},
],
"compounds": [
{
"name": "Run Debugger",
"configurations": ["Launch Chrome Browser", "Launch Node Server"]
}
]
}
切記soucemap支持
調試其他語言
vscode不光支持js語言的調試,同時它也支持其他語言的調試,如:Java、C#、Python等等,如果你需要調試其他語言,可以下載對應的語言的調試插件 Debug Extensions Marketplace
核心原理
從上面的attach模式我們就知道目標程序啓動debug模式後,可以和不同的調試UI進行連接通信,然後完成一系列的調試,而調試的核心就是debugger和UI進行數據通信的形式,只要兩端根據協商好的協議進行數據的傳輸,就可以完成一系列操作
Chrome DevTools Protocol(CDP)
Chrome DevTools Protocol (CDP) 是由 Google 提供的一套調試協議,用於調試、診斷、分析和操作運行中的 Chrome 瀏覽器或其他基於 Chromium 的環境。它允許開發者通過遠程調用控制瀏覽器的行為,比如攔截網絡請求、調試 JavaScript、操作 DOM、性能分析等
開啓Protocol Monitor:
查看Protocol Monitor:
Debug Adapter Protocol (DAP)
VSCode 使用 Debug Adapter Protocol (DAP) 作為調試的標準協議。由於vscode支持多種語言的調試,因此中間使用適配協議,不同語言的調試器是要對接了對應的適配器數據定義,就可以完成數據通信
你也可以直接閲讀官方的「Debugging Architecture of VSCode」
參考文檔
- debugging
- typescript-debugging
- nodejs-debugging
- vscode-js-debug options
- vscode debug recipes
- vue webpack5 debuggers
由於圖片和格式解析問題,可前往 閲讀原文