【Node.js】如何調(diào)試你的 Node.js 代碼?
很多時候,我苦惱于 Node.js 的調(diào)試,只會使用 console.log 這種帶有侵入性的方法,但是其實 Node.js 也可以做到跟瀏覽器調(diào)試一樣的方便。
本文環(huán)境:
mac
Chrome?94.0.4606.81
node?v12.12.0
vscode?Version:?1.61.1
本文示例
本文示例采用的是之前探索洋蔥模型的,僅有一個文件,就是根目錄下 index.js,如下:
const?Koa?=?require('koa');
const?app?=?new?Koa();
console.log('test')
//?中間件1
app.use((ctx,?next)?=>?{
??console.log(1);
??next();
??console.log(2);
});
//?中間件?2?
app.use((ctx,?next)?=>?{
??console.log(3);
??next();
??console.log(4);
});
app.listen(9000,?()?=>?{
????console.log(`Server?is?starting`);
});
V8 Inspector Protocol + Chrome DevTools
v8 Inspector Protocol 是 nodejs v6.3 新加入的調(diào)試協(xié)議,通過 websocket與 Client/IDE 交互,同時基于 Chrome/Chromium 瀏覽器的 devtools 提供了圖形化的調(diào)試界面。
我們進(jìn)入項目根目錄,執(zhí)行(留意這個 8888 端口,后面會用到):
node?--inspect=8888?index.js
結(jié)果如下:

結(jié)果出來一個鏈接——ws://127.0.0.1:8888/5f5c59fc-d42b-4ab0-be15-6feb1a05ed2d。這個鏈接是 Node.js 和 Chrome 之前通信的 websocket 地址,通過 websocket 通信,我們可以在 Chrome 中實時看到 Node.js 的結(jié)果。
如何進(jìn)入 Chrome 的調(diào)試界面
第一種方式(自己嘗試無效)
打開 http://localhost:8888/json/list,其中 8888 是上面 --inspect 的參數(shù)。
[
????{
????????"description":?"node.js?instance",
????????"devtoolsFrontendUrl":?"chrome-devtools://devtools/bundled/js_app.html?experiments=true&v8only=true&ws=localhost:8888/5f5c59fc-d42b-4ab0-be15-6feb1a05ed2d",
????????"devtoolsFrontendUrlCompat":?"chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=localhost:8888/5f5c59fc-d42b-4ab0-be15-6feb1a05ed2d",
????????"faviconUrl":?"https://nodejs.org/static/images/favicons/favicon.ico",
????????"id":?"5f5c59fc-d42b-4ab0-be15-6feb1a05ed2d",
????????"title":?"index.js",
????????"type":?"node",
????????"url":?"file:///Users/gpingfeng/Documents/Personal/Test/test-onion/index.js",
????????"webSocketDebuggerUrl":?"ws://localhost:8888/5f5c59fc-d42b-4ab0-be15-6feb1a05ed2d"
????}
]
很多資料說,可以通過 devtoolsFrontendUrl 就可以直接訪問到,但嘗試了一下,并沒有成功。【可能跟我的環(huán)境有關(guān)】
第二種方式
查了一下資料,在 stackoverflow[1] 找到對應(yīng)的方案,如下:
devtools://devtools/bundled/inspector.html?experiments=true&ws=127.0.0.1:8888/5f5c59fc-d42b-4ab0-be15-6feb1a05ed2d
其中 devtools://devtools/bundled/inspector.html?experiments=true 是固定的,ws 參數(shù)對應(yīng)的就是 websocket 地址。
可以看到界面如下:

第三種方式
Chrome 瀏覽器打開 HTTP 監(jiān)聽接口頁面,打開 dev tool,執(zhí)行完 node --inspect=8888 index.js 后可以看到這個圖標(biāo),點擊一下:

就可以出現(xiàn)跟瀏覽器一樣的調(diào)試頁面,比如 Sources Panel查看腳本、Profile Panel 監(jiān)測性能等。

另外,可以訪問訪問 chrome://inspect/#devices,可以看到當(dāng)前瀏覽器監(jiān)聽的所有 inspect。

Vscode 調(diào)試
除了瀏覽器之外,各大主流的 IDE 都支持 Node.js 的調(diào)試,本文以 Vscode 為例。
Launch Configuration
打開調(diào)試頁面,給我們 Node 項目添加一個 launch 配置:

選擇 Node.js

這樣就會在項目根目錄生成對應(yīng)的文件 .vscode/launch.json(當(dāng)然你也可以手動創(chuàng)建),其中 program 指的就是文件入口,${workspaceFolder} 指的是根目錄。
{
??//?Use?IntelliSense?to?learn?about?possible?attributes.
??//?Hover?to?view?descriptions?of?existing?attributes.
??//?For?more?information,?visit:?https://go.microsoft.com/fwlink/?linkid=830387
??"version":?"0.2.0",
??"configurations":?[
????{
??????"type":?"pwa-node",
??????"request":?"launch",
??????"name":?"Launch?Program",
??????"skipFiles":?[
????????"/**"
??????],
??????"program":?"${workspaceFolder}/index.js"
????}
??]
}
按 F5、或者點擊如下按鈕:

結(jié)果:

可以看到,在左側(cè)可以顯示當(dāng)前作用域的值,調(diào)用堆棧等信息,右上方亦可逐步調(diào)試函數(shù)、重啟等功能,非常強(qiáng)大。
Attach to Node Process Action
通過 Attach to Node Process Action 的方式,我們可以直接調(diào)試運(yùn)行中的 Node.js 進(jìn)程。
比如我們先啟動項目——npm run start。
然后 command + shift + p(window Ctrl+Shift+p),輸入 Attach to Node Process Action,回車,然后選中運(yùn)行中進(jìn)程再回車,就可以跟上面配置一樣調(diào)試代碼了。


總結(jié)
本文總結(jié)了兩種常見的調(diào)試 Node.js 的方式。第一種 Node.js 通過 websocket 的方式將信息傳遞給 Chrome 瀏覽器,我們直接在 Chrome 中進(jìn)行調(diào)試。第二種就是通過 Vscode Launch Configuration,自定義配置的方式進(jìn)行調(diào)試。通過 Attach to Node Process Action 的方式,可以便捷的調(diào)試正在運(yùn)行的 Node.js 代碼,而不需要配置。
參考資料
[1]stackoverflow: https://stackoverflow.com/questions/62066780/chrome-devtools-opens-as-a-search-rather-then-the-dev-tools-themselves
