使用 ndb 調試你的 Node.js 項目

使用 ndb 調試你的 Node.js 項目

來自專欄 ThinkJS64 人贊了文章

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

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


V8 Inspector

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

使用 --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.jsndb npm run testndb mochandb .

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

  • 斷點調試,非同步方法單步調試
  • 控制台預執行顯示(需要 Node.js >= 10)
  • JS 樣本分析
  • 內存分析
  • 本地終端

使用 ndb 進行 ThinkJS 調試

下面以基於 ThinkJS 開發的 Node.js 項目 Firekylin 為例,簡單看看如何使用 ndb 進行斷點調試。

使用 ndb 調試 Node.js 項目 https://www.zhihu.com/video/1009402152439115776

可以看到基本上調試的流程非常的簡單,並且自動適配了多進程項目(視頻中啟了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順利~

參考資料:

  • 《Supercharge your debugging experience for Node.js》
  • 《DevTrends #32: ndb, whats new in Chrome 68》

推薦閱讀:

零後端基礎想搭建一個高可用的node服務,需要學習什麼,有什麼比較好的教程或者開源練手項目么?
跟我學Nodejs(三)
別人家的node都是100萬級別的,我的怎麼5000+伺服器就開始主動斷開連接了?
nodejs工程師一般工作內容是什麼?

TAG:Nodejs | ThinkJS | 調試器 |