nodejs 的調(diào)試 debug


簡介
對于開發(fā)者來說,在開發(fā)應用程序的過程中,往往為了開發(fā)方便和解決 bug 需要借助于編程語言的調(diào)試功能。一般來說我們需要借助于強大 IDE 的調(diào)試功能來完成這項工作。nodejs 也不例外。
今天我們來詳細介紹一下如何調(diào)試 nodejs 程序。
開啟 nodejs 的調(diào)試
還記得之前我們講到的 koa 程序嗎?本文將會以一個簡單的 koa 服務端程序為例,來展開 nodejs 的調(diào)試。
先看下一個簡單的 koa 服務 app.js:
上面的程序開啟了 3000 端口,建立了一個 http 服務。每次請求的時候,都會返回 hello World,非常的簡單。
要想運行上面的程序,我們需要執(zhí)行 node app.js。 這會執(zhí)行 app.js 但是并不會開啟調(diào)試功能。
怎么進行調(diào)試呢?
我們需要加上 –inspect 參數(shù):
上面的代碼將會開啟 nodejs 的調(diào)試功能。
我們看下輸出結(jié)果:
結(jié)果告訴了我們兩件事情,第一件事情就是 debugger 監(jiān)聽的端口。默認情況下將會開啟 127.0.0.1 的 9229 端口。并且分配了一個唯一的 UUID 以供區(qū)分。
第二件事情就是告訴我們 nodejs 使用的調(diào)試器是 Inspector。
Inspector 是 nodejs 8 之后引入的,如果是在 nodejs 7 之前,那么使用的是 legacy debugger。
調(diào)試的安全性
如果 debugger 連接到了 nodejs 運行環(huán)境中,如果有惡意攻擊者的話,這個惡意攻擊者可以在 nodejs 環(huán)境中運行任意代碼。這會給我們的程序帶來很大的安全隱患。
所以我們一定要注意調(diào)試的安全性。一般來說,我們不建議進行遠程調(diào)試。
默認情況下 –inspect 綁定的是 127.0.0.1,這樣就只允許本地程序訪問。并且任何本地運行的程序都有權限進行該程序的調(diào)試。
如果我們真的想將 debug 程序暴露給外部程序的話,那么可以指明本機的外網(wǎng) IP 地址或者 0.0.0.0(表示任何地址,無限制),這樣遠程機子就可以進行遠程調(diào)試了。
如果我們想進行安全的 remote debug 該怎么處理呢?
首先,我們要開啟本地的 debug:
然后我們可以搭建一個 ssh 隧道,將本地的 9221 端口映射到遠程服務器的 9229 端口:
這樣我們就可以通過連接本地的 9221 端口,進行遠程調(diào)試了。
使用 WebStorm 進行 nodejs 調(diào)試
JetBrains 出品的 WebStorm 可謂是開發(fā) nodejs 的利器,WebStorm 自帶有 debug 選項,如果開啟該選項,則會在后臺開啟 –inspect:

使用 WebStorm 來進行調(diào)試和使用 IDEA 來進行 java 程序調(diào)試類似,這里就不多介紹了。
使用 Chrome devTools 進行調(diào)試
使用 Chrome devTools 進行調(diào)試的前提是我們已經(jīng)開啟了 –inspect 模式。
在 chrome 中輸入 chrome://inspect:

我們可看到 chrome inspect 的界面,如果你本地已經(jīng)有開啟 inspect 的 nodejs 程序的話,在 Remote Target 中就可以直接看到。
選中你要調(diào)試的 target,點擊 inspect,即可開啟 Chrome devTools 調(diào)試工具:

你可以對程序進行 profile,也可以進行調(diào)試。
這里我們關注的是調(diào)試,所以轉(zhuǎn)到 source 一欄,添加你要調(diào)試的程序的源代碼:

加入斷點即可開始調(diào)試了。和在 chrome 中調(diào)試 web 端的 js 是一樣的。
使用 node-inspect 來進行調(diào)試
其實 nodejs 有一個自帶的調(diào)試工具,叫做 node-inspect,這是一個 cli 的調(diào)試工具。我們看一下怎么使用。
我們直接使用:
node inspect 做了兩件事情,第一件事情就是生成子程序去運行 node –inspect app.js,第二件事情就是在主程序中運行 CLI 調(diào)試窗口。
這個 CLI 調(diào)試程序為我們提供了一些非常有用的命令:
Stepping
cont, c: 繼續(xù)執(zhí)行
next, n: Step 到下一步
step, s: Step in
out, o: Step out
pause: 暫停運行的代碼
Breakpoints
setBreakpoint(), sb(): 在當前行設置斷點
setBreakpoint(line), sb(line): 在指定的行設置斷點
setBreakpoint(‘fn()’), sb(…): 在指定的 function 中設置斷點
setBreakpoint(‘script.js’, 1), sb(…): 在指定的腳本文件中設置斷點
clearBreakpoint(‘script.js’, 1), cb(…): 從文件中清除斷點
Information
backtrace, bt: 打印當前 execution frame 的 backtrace 信息
list(5): 列出源代碼前后的 5 行
watch(expr): 添加監(jiān)聽表達式
unwatch(expr): 刪除監(jiān)聽表達式
watchers: 列出所有的 watchers
repl: 打開 repl 表達式
exec expr: 執(zhí)行表達式
通過上面的命令,我們可以在 CLI 中進行比較復雜的調(diào)試活動。
其他的 debug 客戶端
除了上面我們講到的幾個之外,我們還可以使用 vscode,Visual Studio ,Eclipse IDE 等來進行 nodejs 的調(diào)試,這里就不一一詳細介紹了。
感興趣的朋友可以自行探索。