使用 ndb 除錯你的 Node.js 專案

ThinkJS發表於2019-03-03

程式碼除錯按照除錯方式大致分為 日誌(Log)斷點(Breakpoint) 兩種辦法。其中日誌就是手動的在程式碼中增加日誌列印獲取過程資訊來判斷問題。這種方法的好處是除錯簡單,一個對業務熟練的工程師通過線上良好的日誌記錄可以非常快的發現業務問題。但是它的缺點也非常明顯,獲取的內容比較單一,動態除錯需要不斷的在業務中增加日誌列印程式碼。

於是乎斷點除錯出現了。斷點除錯類似於中醫的望聞問切,我們通過在需要觀察的點打上斷點就能詳細的獲取到程式執行到該點時的所有上下文,並利用單步除錯逐一觀察程式執行狀況,準確判斷出問題的地方。另外利用 Chrome DevTool 我們也可以隨時對線上業務進行除錯,可以說是非常方便了。

V8 Inspector

在前端使用 Chrome DevTool 進行斷點除錯已經是非常成熟了,在 Node.js(6.3+) 中也自帶了一個類似的偵錯程式,主要是在 Node 內部實現了一套 v8 偵錯程式通訊協議。啟動的時候新增 --inspect 引數,我們就能得到 Chrome DevTools 除錯介面了,剩下的除錯過程就和正常的 Chrome 除錯是一樣了。

1_32J7CSAzBtm68CwiVS0Ukw.png

:Users:lizheming:Desktop:1_-W3U7eUzBnnDu6dTlx9TnQ.jpg

使用 --inspect 除錯極大的方便了 Node.js 開發,讓服務端除錯也有了類似前端除錯一樣的體驗。除了直接開啟 DevTools 除錯,VSCode, WebStorm 等開發工具也將其整合到了編輯器中,不過內部的原理是類似的。不過人無完人,在使用過程中 Node Inspector 除錯也存在著一些缺點:

  • 需要在 node 命令後增加 --inspect 引數,對於一些第三方命令啟動無法直接支援除錯,例如 webpack, ava, mocha...
  • 多程式除錯非常的麻煩,特別是子程式頻繁的銷燬的時候,需要外部手動的監聽程式的建立並手工將程式和除錯工具進行通訊對接

注: 雖然 VSCode 使用的是 Inspector Protocol 模式,不過在 1.22 的版本中已經能夠自動繫結多程式監聽埠了,具體的話可以檢視天豬大大的《VSCode 除錯 Egg 完美版》

ndb

兩週前 Chrome 實驗室開源了一款新的除錯工具,也就是我們今天的主角 —— ndb。它提供了更良好的除錯體驗,正如官方倉庫所說,它為我們帶來了如下一些特性:

  1. 子程式自動檢測和除錯接入
  2. 支援在模組載入前進行斷電
  3. 支援在除錯工具中直接編輯檔案,儲存後自動更新到本地檔案
  4. 預設情況下,ndb 會對引用的所有專案資料夾外的指令碼開啟黑盒模式讓我們能更專注業務程式碼。專案資料夾外的指令碼包括 Node.js 自帶的模組檔案(例如 _stream_wrap.js, async_hooks.js, fs.js 等)。當然你可以在設定中修改“Blackbox anything outside working dir”配置來關閉這個功能。

安裝

npm install -g ndb
複製程式碼

首先要確保你的 Node.js 環境 >= 8.0.0,然後使用 npm install 就可以非常方便的完成安裝。由於 ndb 依賴 Puppeteer 安裝過程中會去下載 Chromium 所以下載過程可能會有一定的時間,請各位同學耐心等待。如果有碰上許可權問題官方提示可以嘗試增加 --unsafe-perm=true --allow-root 引數解決。

使用

不同於 node --inspect 的複雜使用,ndb 的使用方式非常的簡單。在所有你想要進行除錯指令碼執行前加入 ndb 命令即可,甚至還能直接使用 ndb 命令啟動指令碼。以下是從倉庫示例中引用的一些啟動方式:

ndb node server.js

ndb npm run test

ndb mocha

ndb .
複製程式碼

--inspect 一樣,執行命令後就會彈出 Chrome DevTools 除錯介面。在這個特製的除錯介面中,你可以:

  • 斷點除錯,非同步方法單步除錯
  • 控制檯預執行顯示(需要 Node.js >= 10)
  • JS 樣本分析
  • 記憶體分析
  • 本地終端

使用 ndb 進行 ThinkJS 除錯

下面以基於 ThinkJS 開發的 Node.js 專案 Firekylin 為例,簡單看看如何使用 ndb 進行斷點除錯。

(由於掘金目前暫不支援嵌入視訊,所以需要大家跳轉到騰訊視訊中觀看。)
v.qq.com/x/page/t074…

可以看到基本上除錯的流程非常的簡單,並且自動適配了多程式專案(視訊中啟了8個程式),解決了之前使用 --inspect 的兩個問題。另外在底部的控制檯由於是 REPL 環境,可以實時獲取到斷點處當前環境的資料,例如我們可以列印 process.memoryUsage() 檢視當前的記憶體使用情況。

除了斷點除錯之外,ndb 也支援記憶體和效能分析,可以幫助我們分析記憶體洩露和。具體的也可以參考一下官方文件《Chrome DevTool 解決記憶體問題》

ndb 的問題

還是那句話人無完人,ndb 目前使用下來還是覺得有一點不太舒服的地方。主要是表現在檔案更新方面,目前程式碼編寫還是在程式碼編輯器中,除錯需要到 ndb 介面上,頻繁的切換感覺有點不爽。希望後續 VSCode 能儘快將 ndb 引入替換現有的除錯工具就非常方便了。

有同學會說為什麼不在 ndb 上直接編輯檔案呢,畢竟支援檔案編輯儲存也是 ndb 作為除錯工具的一大特色。這是因為在多程式環境下每個程式的除錯是相互獨立的,你在一個程式上的檔案修改只能反映在這個修改的程式上,不能在所有程式上生效,和我們本地操作檔案不太一樣,使用上需要注意。不過這個也比較好解決,除錯的時候只開啟一個程式就可以了。

後記

Node.js 已經有越來越多的工具可以幫助我們進行斷點除錯了,從早期的 Debug Protocol 到前兩年開始支援的 V8 Inspector Protocol 到現在的 ndb,我們看到了技術正在一步步的朝前走著,當然我們這裡需要先感謝下 Chrome 工程師們,感謝他們開發出了這麼棒的工具。當然除了斷點單步除錯之外,日誌除錯也有它存在的必要,兩者可以相輔相成沒有孰好孰壞之分。

最後,送一張圖給大家祝大家新的一週改BUG順利~

改bug

參考資料:

相關文章