Node.js 中的除錯工具
簡介
在 JavaScript 伺服器端開發的過程中,錯誤與除錯往往是最耗時的環節。即使在瀏覽器內已經有成熟的除錯工具,Node.js 仍有自己的挑戰:非同步流程、事件迴圈與外部資源的互動,都可能讓錯誤訊息變得模糊不清。掌握適合的除錯工具,不僅能快速定位問題,還能提升程式碼可維護性與開發效率。
本篇文章針對 Node.js 除錯工具 進行系統性說明,從最簡單的 console 訊息,到完整的 Node Inspector、VS Code Debugger、以及第三方的 debug 套件,逐一示範實作方式與注意事項,讓初學者也能在實務專案中得心應手。
核心概念
1. console 系列 – 最基礎的除錯手段
console.log、console.error、console.warn、console.table 等方法是最直接的除錯方式。雖然簡易,但配合 字串模板、顏色標記(如 chalk)可以讓訊息更具可讀性。
// 範例 1:使用 console.log 輸出變數與執行時間
const start = Date.now();
const data = { id: 123, name: 'Alice', age: 28 };
console.log('[INFO] 取得資料:', data);
console.log(`[DEBUG] 執行時間: ${Date.now() - start}ms`);
小技巧:在大型專案中,建議建立自己的
logger模組,統一格式與等級(info、warn、error)。
2. node --inspect 與 Chrome DevTools
Node.js 從 v6 起內建 V8 Inspector,可以透過 --inspect 或 --inspect-brk 參數啟動遠端除錯,然後使用 Chrome DevTools 連線。
# 範例 2:啟動帶有除錯功能的 Node 程式
node --inspect-brk server.js
啟動後,終端機會顯示類似 ws://127.0.0.1:9229/... 的網址,點擊 Chrome 的 chrome://inspect → Open dedicated DevTools for Node 即可連線。
在 DevTools 中,你可以:
- 斷點(Breakpoint)
- 即時檢視變數(Scope / Watch)
- 執行單步(Step over / Step into)
- 呼叫堆疊(Call Stack)
提示:若想在程式碼的特定位置自動暫停,只要加入
debugger;陳述式。
// 範例 3:使用 debugger 陳述式
function calculate(a, b) {
debugger; // 程式執行到此會自動暫停
return a + b;
}
calculate(5, 7);
3. VS Code 內建除錯器
Visual Studio Code(以下簡稱 VS Code)提供完整的 Node.js 除錯體驗,無需離開編輯器即可設定斷點、檢視變數、觀察呼叫堆疊。只要在專案根目錄建立 .vscode/launch.json:
// 範例 4:VS Code 除錯設定
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}/app.js",
"runtimeArgs": ["--inspect-brk"],
"console": "integratedTerminal"
}
]
}
設定完成後,按下 F5(或點擊左側除錯圖示 → 開始除錯)即可進入除錯模式。VS Code 甚至支援 自動重啟(nodemon)與 環境變數 的注入。
4. debug 套件 – 讓除錯訊息可切換
debug 是由 TJ Holowaychuk 開發的輕量級除錯工具,透過環境變數 DEBUG 控制訊息顯示,適合在 開發與生產 環境間切換。
# 安裝 debug 套件
npm install debug --save-dev
// 範例 5:使用 debug 套件
const debug = require('debug')('app:server');
function startServer(port) {
debug('Server is starting on port %d', port);
// ... 其他程式碼
}
startServer(3000);
執行時只要設定 DEBUG=app:*,即會看到 debug 輸出的訊息;若未設定,則不會有任何輸出,保持 console 清潔。
5. 捕捉未處理的例外與 Promise 錯誤
在 Node.js 中,未捕捉的例外(uncaughtException)與 未處理的 Promise(unhandledRejection)會導致程式直接崩潰。使用 process 事件可以在崩潰前記錄錯誤,並安全關閉服務。
// 範例 6:全域錯誤監聽
process.on('uncaughtException', (err) => {
console.error('[FATAL] 未捕捉的例外:', err);
// 最好寫入日誌,然後優雅關閉
process.exit(1);
});
process.on('unhandledRejection', (reason, promise) => {
console.warn('[WARN] 未處理的 Promise 拒絕:', reason);
});
注意:即使有上述監聽,仍建議在每個非同步操作內部自行
try/catch或.catch(),避免錯誤蔓延。
常見陷阱與最佳實踐
| 陷阱 | 可能的後果 | 解決方案 |
|---|---|---|
直接使用 console.log 於大量資料 |
產生龐大輸出、降低效能,且難以搜尋 | 使用 log level(如 debug、winston)並限制輸出大小 |
忘記移除 debugger; |
生產環境卡在斷點,服務無法正常運作 | 於 CI/CD 階段執行 lint(no-debugger)檢查 |
未設定 --inspect-brk |
程式在除錯前已執行完畢,無法捕捉早期錯誤 | 使用 --inspect-brk 讓程式在第一行暫停 |
只依賴 uncaughtException |
可能錯過 Promise 拒絕的錯誤 | 同時監聽 unhandledRejection |
在生產環境開啟 DEBUG=* |
大量日誌寫入磁碟,造成 I/O 壓力 | 僅在 開發或測試 環境開啟,生產使用 log rotation |
最佳實踐總結:
- 統一日誌框架:使用
winston、pino或debug,避免散落的console.log。 - 斷點與觀察變數:在非同步回呼或
async/await區塊前後放置斷點,確保 上下文 正確。 - 自動化測試:結合 Jest、Mocha 的錯誤捕捉,提前發現例外。
- CI/CD 檢查:加入 ESLint 規則
no-console、no-debugger,保證程式碼品質。
實際應用場景
場景一:API 伺服器的性能瓶頸
在一個使用 Express 建構的 REST API 中,某個端點回傳速度異常緩慢。使用 node --inspect 連結 Chrome DevTools,於 Event Loop 面板觀察 Timers 與 CPU 使用情況,發現某個資料庫查詢未使用索引,導致阻塞。透過斷點定位到 await db.query(...) 前後的變數,最終優化 SQL,將回應時間從 2.3 秒降至 180ms。
場景二:非同步錯誤導致服務 Crash
一個背景工作(worker)使用 setInterval 定時抓取外部 API。某次外部 API 回傳 500,程式碼只寫了 await fetch(...);,未加 .catch()。結果 unhandledRejection 觸發,服務直接關閉。加入全域 process.on('unhandledRejection') 以及每個 fetch 的 .catch(),不僅避免 Crash,還能把錯誤寫入日誌,方便後續追蹤。
場景三:多開發者協作的除錯流程
團隊使用 VS Code 與 GitHub Codespaces,每位開發者在本機或遠端容器中執行 npm run dev(內含 --inspect)。除錯設定寫在 .vscode/launch.json,所有人只要按 F5 即可進入除錯模式。透過 Watch 功能觀察 process.env.NODE_ENV、req.body 等關鍵變數,快速定位錯誤來源,提升開發效率。
總結
Node.js 的除錯工具從最簡單的 console 訊息,到功能完整的 V8 Inspector、VS Code Debugger,再到可切換的 debug 套件與全域錯誤監聽,每一層都提供了不同的粒度與便利性。掌握這些工具的使用方法,配合 良好的日誌策略、斷點技巧 與 全域例外處理,即可在開發階段快速找出問題,並在生產環境保持穩定。
關鍵要點:
- 先從
console→debugger→--inspect→ IDE 除錯的層層遞進。- 絕不在生產環境直接使用
debugger;或開啟DEBUG=*。- 結合 log framework 與 全域錯誤監聽,建立可觀測、可維護的 Node.js 應用。
透過本文的範例與最佳實踐,你已具備在任何 Node.js 專案中有效除錯的基礎。現在就把這些技巧應用到自己的程式碼裡,讓除錯不再是痛苦的「找錯」過程,而是提升程式品質的 加速器。祝開發順利!