Node 除錯工具入門教程

阮一峰發表於2018-03-20

JavaScript 程式越來越複雜,除錯工具的重要性日益凸顯。客戶端指令碼有瀏覽器,Node 指令碼怎麼除錯呢?

2016年,Node 決定將 Chrome 瀏覽器的"開發者工具"作為官方的除錯工具,使得 Node 指令碼也可以使用圖形介面除錯,這大大方便了開發者。

本文介紹如何使用 Node 指令碼的除錯工具。

一、示例程式

為了方便講解,下面是一個示例指令碼。首先,新建一個工作目錄,並進入該目錄。


$ mkdir debug-demo
$ cd debug-demo

然後,生成package.json檔案,並安裝 Koa 框架和 koa-route 模組。


$ npm init -y
$ npm install --save koa koa-route

接著,新建一個指令碼app.js,並寫入下面的內容。


// app.js
const Koa = require('koa');
const router = require('koa-route');

const app = new Koa();

const main = ctx => {
  ctx.response.body = 'Hello World';
};

const welcome = (ctx, name) => {
  ctx.response.body = 'Hello ' + name;
};

app.use(router.get('/', main));
app.use(router.get('/:name', welcome));

app.listen(3000);
console.log('listening on port 3000');

上面程式碼是一個簡單的 Web 應用,指定了兩個路由,訪問後會顯示一行歡迎資訊。如果想了解程式碼的詳細含義,可以參考 Koa 教程

二、啟動開發者工具

現在,執行上面的指令碼。


$ node --inspect app.js

上面程式碼中,--inspect引數是啟動除錯模式必需的。這時,開啟瀏覽器訪問http://127.0.0.1:3000,就可以看到 Hello World 了。

接下來,就要開始除錯了。一共有兩種開啟除錯工具的方法,第一種是在 Chrome 瀏覽器的位址列,鍵入 chrome://inspect或者about:inspect,回車後就可以看到下面的介面。

在 Target 部分,點選 inspect 連結,就能進入除錯工具了。

第二種進入除錯工具的方法,是在 http://127.0.0.1:3000 的視窗開啟"開發者工具",頂部左上角有一個 Node 的綠色標誌,點選就可以進入。

三、除錯工具視窗

除錯工具其實就是"開發者工具"的定製版,省去了那些對伺服器指令碼沒用的部分。

它主要有四個皮膚。

  • Console:控制檯
  • Memory:記憶體
  • Profiler:效能
  • Sources:原始碼

這些皮膚的用法,基本上跟瀏覽器環境差不多,這裡只介紹 Sources (原始碼)皮膚。

四、設定斷點

進入 Sources 皮膚,找到正在執行的指令碼app.js

在第11行(也就是下面這一行)的行號上點一下,就設定了一個斷點。


ctx.response.body = 'Hello ' + name;

這時,瀏覽器訪問 http://127.0.0.1:3000/alice ,頁面會顯示正在等待伺服器返回。切換到除錯工具,可以看到 Node 主執行緒處於暫停(paused)階段。

進入 Console 皮膚,輸入 name,會返回 alice。這表明我們正處在斷點處的上下文(context)。

再切回 Sources 皮膚,右側可以看到 Watch、Call Stack、Scope、Breakpoints 等摺疊項。開啟 Scope 摺疊項,可以看到 Local 作用域和 Global 作用域裡面的所有變數。

Local 作用域裡面,變數name的值是alice,雙擊進入編輯狀態,把它改成bob

然後,點選頂部工具欄的繼續執行按鈕。

頁面上就可以看到 Hello bob 了。

命令列下,按下 ctrl + c,終止執行app.js

五、除錯非服務指令碼

Web 服務指令碼會一直在後臺執行,但是大部分指令碼只是處理某個任務,執行完就會終止。這時,你可能根本沒有時間開啟除錯工具。等你開啟了,指令碼早就結束執行了。這時怎麼除錯呢?


$ node --inspect=9229 -e "setTimeout(function() { console.log('yes'); }, 30000)"

上面程式碼中,--inspect=9229指定除錯埠為 9229,這是除錯工具預設的通訊埠。-e引數指定一個字串,作為程式碼執行。

訪問chrome://inspect,就可以進入除錯工具,除錯這段程式碼了。

程式碼放在setTimeout裡面,總是不太方便。那些執行時間較短的指令碼,可能根本來不及開啟除錯工具。這時就要使用下面的方法。


$ node --inspect-brk=9229 app.js

上面程式碼中,--inspect-brk指定在第一行就設定斷點。也就是說,一開始執行,就是暫停的狀態。

六、忘了寫 --inspect 怎麼辦?

開啟除錯工具的前提是,啟動 Node 指令碼時就加上--inspect引數。如果忘了這個引數,還能不能除錯呢?

回答是可以的。首先,正常啟動指令碼。


$ node app.js

然後,在另一個命令列視窗,查詢上面指令碼的程式號。


$ ps ax | grep app.js 

30464 pts/11   Sl+    0:00 node app.js
30541 pts/12   S+     0:00 grep app.js

上面命令中,app.js的程式號是30464

接著,執行下面的命令。


$ node -e 'process._debugProcess(30464)'

上面命令會建立程式 30464 與除錯工具的連線,然後就可以開啟除錯工具了。

還有一種方法,就是向指令碼程式傳送 SIGUSR1 訊號,也可以建立除錯連線。


$ kill -SIGUSR1 30464

七、參考連結

(完)

相關文章