Nodejs 調(diào)試代碼一

很長一段時間,調(diào)試 Nodejs 代碼都是通過在代碼里寫 console.log() 進(jìn)行的。在 infoq 上看到一篇文章,是說十倍效率工程師有哪些特質(zhì),其中一點(diǎn)就是擅長調(diào)試與測試。這給了我很大動力去弄明白這些之前模糊的概念。

調(diào)試服務(wù)端

創(chuàng)建 index.js,在服務(wù)端想要運(yùn)行該文件,需要在終端輸入 $ node index.js。
node 程序 會讀取 index.js 源碼,如果 index.js 中引用了其它 js 文件,依次讀取源碼,最后執(zhí)行。

(安裝的 Nodejs 軟件里包含很多個子程序,node 是其中一個程序,用于執(zhí)行 js 文件)

圖1

在調(diào)試 Nodejs 代碼時,我們希望代碼能一行行執(zhí)行,而不是像 node 程序那樣將整個源碼都跑完,這時候需要用 Nodejs 內(nèi)置的 調(diào)試器程序 去運(yùn)行 index.js。

圖2

總結(jié)下目前了解的概念:

  • 安裝的 Nodejs 軟件包會包含很多子程序,比如 node 程序和調(diào)試器程序;
  • node 程序的特點(diǎn)是一下子將整個代碼都跑完;
  • 調(diào)試器程序的特點(diǎn)是一行行執(zhí)行代碼;

調(diào)試器程序執(zhí)行 js 文件后,會啟一個 websocket 的服務(wù),調(diào)試器程序作為服務(wù)端,只提供與調(diào)試相關(guān)的底層功能,這樣做的好處是開發(fā)人員可以自由選擇調(diào)試客戶端:你可以選擇在終端中調(diào)試,也可以選擇在谷歌瀏覽器中調(diào)試,甚至可以在 Vscode 中調(diào)試,只要你的調(diào)試客戶端連接到調(diào)試服務(wù)端即可。

圖3

創(chuàng)建 index.js 文件作為調(diào)試演示代碼,內(nèi)容如下:

const add = require('./add')

const a = 1
const b = 2

debugger
console.log(add(a, b))

下面分別介紹用不同的調(diào)試器客戶端進(jìn)行調(diào)試。

終端中調(diào)試

Nodejs 也自帶了一個調(diào)試器客戶端,在終端中進(jìn)行調(diào)試。

$ node inspect index.js

node inspect 表示啟動調(diào)試器服務(wù)端,并在終端打開調(diào)試器客戶端。

$  node inspect index.js
< Debugger listening on ws://127.0.0.1:9229/858f5307-2af1-472a-bd73-a2fbe5b8578b
< For help, see: https://nodejs.org/en/docs/inspector
< Debugger attached.
Break on start in index.js:1
> 1 const add = require('./add')
  2
  3 const a = 1
debug>

第一行 Debugger listening on ws://127.0.0.1:9229/,表示調(diào)試服務(wù)端已經(jīng)啟動了,并且監(jiān)聽著 9229 這個端口。
第三行 Debugger attached,表示調(diào)試器客戶端已經(jīng)連接到調(diào)試器服務(wù)端了。

輸入 help 可以查看調(diào)試器有哪些用法。

debug> help
run, restart, r       Run the application or reconnect
kill                  Kill a running application or disconnect

cont, c               Resume execution
next, n               Continue to next line in current file
step, s               Step into, potentially entering a function
out, o                Step out, leaving the current function
backtrace, bt         Print the current backtrace
list                  Print the source around the current line where execution
                      is currently paused

setBreakpoint, sb     Set a breakpoint
clearBreakpoint, cb   Clear a breakpoint

......

debug>

輸入 n,執(zhí)行下一行代碼。

debug> n
break in index.js:3
  1 const add = require('./add')
  2
> 3 const a = 1
  4 const b = 2
  5

輸入 c,跳轉(zhuǎn)到下一個斷點(diǎn)處。

debug> c
break in index.js:6
  4 const b = 2
  5
> 6 debugger
  7 console.log(add(a, b))
  8

還有一些常用的命令,在 help 中可以查看詳細(xì)用法,這里簡要列舉下,就不一一介紹了。

  • restart 重啟調(diào)試器
  • run 開始調(diào)試
  • kill 停止調(diào)試
  • s 單步跳進(jìn)
  • o 單步跳出

Chrome Devtool 中調(diào)試

谷歌瀏覽器的開發(fā)者工具也可以作為調(diào)試客戶端調(diào)試 Nodejs 代碼,只要連接到調(diào)試器服務(wù)端即可。

$ node --inspect-brk index.js
Debugger listening on ws://127.0.0.1:9229/7513b18d-7a62-44c7-a963-84a90eb826a9
For help, see: https://nodejs.org/en/docs/inspector

node --inspect-brk 表示只啟動了調(diào)試器服務(wù)端,監(jiān)聽端口 9229。此時還沒有任何調(diào)試器客戶端連接哦~~

打開谷歌瀏覽器的開發(fā)者工具,左上角可以看到 nodejs 的 logo,點(diǎn)它。

圖4

點(diǎn)擊之后彈出的新窗口就是Chrome Devtools 中調(diào)試 Nodejs 代碼的調(diào)試客戶端。

  • 紅字1:窗體標(biāo)題表示這是 Nodejs 的調(diào)試客戶端;
  • 紅字2(Console):服務(wù)端打印的日志(console.log)也會在這里打印;
  • 紅字3(Sources):服務(wù)端源代碼,調(diào)試器并不會見所有服務(wù)端代碼都推送到這里,只會推送用到的代碼;
  • 紅字4:源碼文件,可以點(diǎn)擊想要打斷點(diǎn)的文件,在右側(cè)打斷點(diǎn)調(diào)試;
  • 紅字5(Scope):變量的具體值在這里可以找到。
圖5

此時回到終端,可以看到多打印一條消息,最后一行表示調(diào)試器客戶端連接到調(diào)試器服務(wù)端了。

$  node --inspect-brk index.js
Debugger listening on ws://127.0.0.1:9229/0a233e15-573b-40a0-956f-76c8e074b5a1
For help, see: https://nodejs.org/en/docs/inspector
Debugger attached.      <=============

為什么打開谷歌瀏覽器的 Chrome Devtools,會自動連接調(diào)試器服務(wù)端呢?

調(diào)試器服務(wù)端默認(rèn)啟動端口是 9229,而 Chrome Devtools 默認(rèn)也會連接 9229 端口。
重新啟動調(diào)試器服務(wù)端,并且指定一個不一樣的端口,此時調(diào)試器服務(wù)端端口變成了 9222。

$  node --inspect-brk=9222 index.js 
Debugger listening on ws://127.0.0.1:9222/967b99ee-b726-4c2b-ba08-dec16f1a531a
For help, see: https://nodejs.org/en/docs/inspector

再次打開瀏覽器,可以看到 Nodejs 的 logo 變成灰色了,也不會主動連接到調(diào)試器服務(wù)端了。此時需要我們手動設(shè)置下 Chrome Devtools 去連接哪個端口。

點(diǎn)擊 Nodejs 的 logo 圖像,在彈出的窗體中選擇 Connection(紅字1),點(diǎn)擊 Add connection(紅字2),在上方的輸入框輸入要監(jiān)聽的端口號保存即可。

圖6

Vscode 中調(diào)試

大多數(shù)開發(fā)者調(diào)試代碼都會選擇 IDE(開發(fā)工具) 進(jìn)行調(diào)試,這里以 Vscode 為例進(jìn)行說明。

用 Vscode 打開 index.js 所在的目錄。

圖7

這里主要介紹下紅字 3 的幾個屬性的含義:

  • type: "node",表示調(diào)試 Nodejs 代碼,如果調(diào)試 PHP 代碼,這里寫成 type: php;
  • request: "launch",launch 表示由 調(diào)試器程序 執(zhí)行 index.js,而不是由 node程序 執(zhí)行 index.js,參考第一點(diǎn)調(diào)試器服務(wù)端。request 還有一個值 attach,下文再介紹;
  • name: "Launch Program",紅字2左邊有個下拉框,name 屬性的值即為下拉框中的值;
  • program: "${workspaceFolder}/index.js",啟動哪個文件,這里表示啟動根目錄下的 index.js 文件。
圖8
  • 紅字1(調(diào)試控制臺):可以看到啟動了調(diào)試器服務(wù)端,監(jiān)聽端口 26199,每次調(diào)試端口都不一樣。Debugger attached 表示調(diào)試客戶端也連接上服務(wù)端了;
  • 紅字2:調(diào)試的相關(guān)操作都在這里;
  • 紅字3:調(diào)試過程中變量和表達(dá)式的值可以在這里查看。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容