Inspector#

穩定性:2 - 穩定

原始碼: lib/inspector.js

node:inspector 模組提供一個 API,用於與 V8 inspector 後端互動。

可以使用下列方式存取

import * as inspector from 'node:inspector/promises';const inspector = require('node:inspector/promises');

import * as inspector from 'node:inspector';const inspector = require('node:inspector');

Promises API#

穩定性:1 - 實驗性

類別:inspector.Session#

inspector.Session 用於將訊息傳送至 V8 inspector 後端,並接收訊息回應和通知。

new inspector.Session()#

建立 inspector.Session 類別的新執行個體。inspector 會話需要透過 session.connect() 進行連線,才能將訊息傳送至 inspector 後端。

使用 Session 時,主控台 API 輸出的物件不會釋放,除非我們手動執行 Runtime.DiscardConsoleEntries 指令。

事件:'inspectorNotification'#

在收到來自 V8 Inspector 的任何通知時發出。

session.on('inspectorNotification', (message) => console.log(message.method));
// Debugger.paused
// Debugger.resumed 

注意事項不建議使用具有相同執行緒工作階段的中斷點,請參閱 中斷點支援

也可以只訂閱具有特定方法的通知

事件:<inspector-protocol-method>;#

在收到方法欄位設定為 <inspector-protocol-method> 值的 Inspector 通知時發出。

以下程式片段在 'Debugger.paused' 事件上安裝監聽器,並在程式執行暫停時(例如透過中斷點)列印程式暫停的原因

session.on('Debugger.paused', ({ params }) => {
  console.log(params.hitBreakpoints);
});
// [ '/the/file/that/has/the/breakpoint.js:11:0' ] 

注意事項不建議使用具有相同執行緒工作階段的中斷點,請參閱 中斷點支援

session.connect()#

將工作階段連線到 Inspector 後端。

session.connectToMainThread()#

將工作階段連線到主執行緒 Inspector 後端。如果未在 Worker 執行緒上呼叫此 API,則會擲回例外。

session.disconnect()#

立即關閉工作階段。所有待處理的訊息回呼都會呼叫錯誤。session.connect() 需要呼叫才能再次傳送訊息。重新連線的工作階段會遺失所有檢查器狀態,例如已啟用的代理或已設定的斷點。

session.post(method[, params])#

將訊息張貼到檢查器後端。

import { Session } from 'node:inspector/promises';
try {
  const session = new Session();
  session.connect();
  const result = await session.post('Runtime.evaluate', { expression: '2 + 2' });
  console.log(result);
} catch (error) {
  console.error(error);
}
// Output: { result: { type: 'number', value: 4, description: '4' } } 

V8 檢查器協定的最新版本已發布在 Chrome DevTools 協定檢視器 上。

Node.js 檢查器支援 V8 宣告的所有 Chrome DevTools 協定網域。Chrome DevTools 協定網域提供一個介面,用於與用於檢查應用程式狀態和聆聽執行時間事件的執行時間代理程式之一進行互動。

範例用法#

除了偵錯器外,各種 V8 Profilers 可透過 DevTools 協定取得。

CPU Profiler#

以下範例顯示如何使用 CPU Profiler

import { Session } from 'node:inspector/promises';
import fs from 'node:fs';
const session = new Session();
session.connect();

await session.post('Profiler.enable');
await session.post('Profiler.start');
// Invoke business logic under measurement here...

// some time later...
const { profile } = await session.post('Profiler.stop');

// Write profile to disk, upload, etc.
fs.writeFileSync('./profile.cpuprofile', JSON.stringify(profile)); 
Heap Profiler#

以下範例說明如何使用Heap Profiler

import { Session } from 'node:inspector/promises';
import fs from 'node:fs';
const session = new Session();

const fd = fs.openSync('profile.heapsnapshot', 'w');

session.connect();

session.on('HeapProfiler.addHeapSnapshotChunk', (m) => {
  fs.writeSync(fd, m.params.chunk);
});

const result = await session.post('HeapProfiler.takeHeapSnapshot', null);
console.log('HeapProfiler.takeHeapSnapshot done:', result);
session.disconnect();
fs.closeSync(fd); 

回呼 API#

類別:inspector.Session#

inspector.Session 用於將訊息傳送至 V8 inspector 後端,並接收訊息回應和通知。

new inspector.Session()#

建立 inspector.Session 類別的新執行個體。inspector 會話需要透過 session.connect() 進行連線,才能將訊息傳送至 inspector 後端。

使用 Session 時,主控台 API 輸出的物件不會釋放,除非我們手動執行 Runtime.DiscardConsoleEntries 指令。

事件:'inspectorNotification'#

在收到來自 V8 Inspector 的任何通知時發出。

session.on('inspectorNotification', (message) => console.log(message.method));
// Debugger.paused
// Debugger.resumed 

注意事項不建議使用具有相同執行緒工作階段的中斷點,請參閱 中斷點支援

也可以只訂閱具有特定方法的通知

事件:<inspector-protocol-method>;#

在收到方法欄位設定為 <inspector-protocol-method> 值的 Inspector 通知時發出。

以下程式片段在 'Debugger.paused' 事件上安裝監聽器,並在程式執行暫停時(例如透過中斷點)列印程式暫停的原因

session.on('Debugger.paused', ({ params }) => {
  console.log(params.hitBreakpoints);
});
// [ '/the/file/that/has/the/breakpoint.js:11:0' ] 

注意事項不建議使用具有相同執行緒工作階段的中斷點,請參閱 中斷點支援

session.connect()#

將工作階段連線到 Inspector 後端。

session.connectToMainThread()#

將工作階段連線到主執行緒 Inspector 後端。如果未在 Worker 執行緒上呼叫此 API,則會擲回例外。

session.disconnect()#

立即關閉工作階段。所有待處理的訊息回呼都會呼叫錯誤。session.connect() 需要呼叫才能再次傳送訊息。重新連線的工作階段會遺失所有檢查器狀態,例如已啟用的代理或已設定的斷點。

session.post(method[, params][, callback])#

將訊息發佈至 inspector 後端。收到回應時,將會通知 callbackcallback 是接受兩個選用參數的函式:錯誤和訊息特定的結果。

session.post('Runtime.evaluate', { expression: '2 + 2' },
             (error, { result }) => console.log(result));
// Output: { type: 'number', value: 4, description: '4' } 

V8 檢查器協定的最新版本已發布在 Chrome DevTools 協定檢視器 上。

Node.js 檢查器支援 V8 宣告的所有 Chrome DevTools 協定網域。Chrome DevTools 協定網域提供一個介面,用於與用於檢查應用程式狀態和聆聽執行時間事件的執行時間代理程式之一進行互動。

傳送 HeapProfiler.takeHeapSnapshotHeapProfiler.stopTrackingHeapObjects 指令至 V8 時,您無法將 reportProgress 設為 true

範例用法#

除了偵錯器外,各種 V8 Profilers 可透過 DevTools 協定取得。

CPU profiler#

以下範例顯示如何使用 CPU Profiler

const inspector = require('node:inspector');
const fs = require('node:fs');
const session = new inspector.Session();
session.connect();

session.post('Profiler.enable', () => {
  session.post('Profiler.start', () => {
    // Invoke business logic under measurement here...

    // some time later...
    session.post('Profiler.stop', (err, { profile }) => {
      // Write profile to disk, upload, etc.
      if (!err) {
        fs.writeFileSync('./profile.cpuprofile', JSON.stringify(profile));
      }
    });
  });
}); 
堆配置分析器#

以下範例說明如何使用Heap Profiler

const inspector = require('node:inspector');
const fs = require('node:fs');
const session = new inspector.Session();

const fd = fs.openSync('profile.heapsnapshot', 'w');

session.connect();

session.on('HeapProfiler.addHeapSnapshotChunk', (m) => {
  fs.writeSync(fd, m.params.chunk);
});

session.post('HeapProfiler.takeHeapSnapshot', null, (err, r) => {
  console.log('HeapProfiler.takeHeapSnapshot done:', err, r);
  session.disconnect();
  fs.closeSync(fd);
}); 

常見物件#

inspector.close()#

嘗試關閉所有剩餘的連線,並封鎖事件迴圈,直到所有連線都關閉為止。在所有連線都關閉後,停用檢查器。

inspector.console#

  • <Object> 用於將訊息傳送至遠端檢查器主控台的物件。
require('node:inspector').console.log('a message'); 

檢查器主控台與 Node.js 主控台之間的 API 沒有對等性。

inspector.open([port[, host[, wait]]])#

  • port <number> 監聽檢查器連線的埠號。此參數為選用參數。預設值:CLI 上指定的內容。
  • host <string> 監聽檢查器連線的主機。此參數為選用參數。預設值:CLI 上指定的內容。
  • wait <boolean> 封鎖,直到有客戶端連線。此參數為選用參數。預設值:false
  • 傳回值:<Disposable> 會呼叫 inspector.close() 的 Disposable。

在主機和埠號上啟用檢查器。等同於 node --inspect=[[host:]port],但可以在 node 啟動後以程式化方式執行。

如果 wait 為 true,會封鎖直到客戶端已連線到檢查埠,且流程控制已傳遞給偵錯客戶端。

請參閱 安全性警告,了解 host 參數的使用方式。

inspector.url()#

傳回目前檢查器的 URL,或如果沒有檢查器,則傳回 undefined

$ node --inspect -p 'inspector.url()'
Debugger listening on ws://127.0.0.1:9229/166e272e-7a30-4d09-97ce-f1c012b43c34
For help, see: https://node.dev.org.tw/en/docs/inspector
ws://127.0.0.1:9229/166e272e-7a30-4d09-97ce-f1c012b43c34

$ node --inspect=localhost:3000 -p 'inspector.url()'
Debugger listening on ws://127.0.0.1:3000/51cf8d0e-3c36-4c59-8efd-54519839e56a
For help, see: https://node.dev.org.tw/en/docs/inspector
ws://127.0.0.1:3000/51cf8d0e-3c36-4c59-8efd-54519839e56a

$ node -p 'inspector.url()'
undefined 

inspector.waitForDebugger()#

封鎖直到客戶端(現有的或稍後連線)已傳送 Runtime.runIfWaitingForDebugger 命令。

如果沒有目前檢查器,將擲回例外。

中斷點支援#

Chrome DevTools 通訊協定 Debugger 領域 允許 inspector.Session 附加到程式並設定中斷點,以逐步執行程式碼。

不過,應避免使用由 session.connect() 連線的同執行緒 inspector.Session 設定中斷點,因為被附加並暫停的程式正是偵錯器本身。請改用 session.connectToMainThread() 連線到主執行緒,並在工作執行緒中設定中斷點,或透過 WebSocket 連線使用 Debugger 程式連線。