检查器#

稳定性: 2 - 稳定

源代码: lib/inspector.js

node:inspector 模块提供了一个与 V8 检查器交互的 API。

可以使用以下方法访问它

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 检查器后端,并接收消息响应和通知。

new inspector.Session()#

创建一个新的 inspector.Session 类实例。检查器会话需要通过 session.connect() 连接,才能将消息分派到检查器后端。

使用 Session 时,除非我们手动执行 Runtime.DiscardConsoleEntries 命令,否则控制台 API 输出的对象不会被释放。

事件: 'inspectorNotification'#

当收到来自 V8 检查器的任何通知时发出。

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

警告 使用相同线程会话的断点不推荐,请参阅 断点支持

也可以仅订阅具有特定方法的通知

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

当收到其方法字段设置为<inspector-protocol-method>值的检查器通知时发出。

以下代码片段在 'Debugger.paused' 事件上安装了一个监听器,并在程序执行暂停时(例如通过断点)打印程序暂停的原因

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

警告 使用相同线程会话的断点不推荐,请参阅 断点支持

session.connect()#

将会话连接到检查器后端。

session.connectToMainThread()#

将会话连接到主线程检查器后端。如果此 API 未在 Worker 线程上调用,则会抛出异常。

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 协议域提供了一个接口,用于与用于检查应用程序状态和监听运行时事件的运行时代理之一进行交互。

示例用法#

除了调试器之外,还可以通过 DevTools 协议使用各种 V8 分析器。

CPU 分析器#

以下示例展示了如何使用 CPU 分析器

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)); 
堆分析器#

以下示例展示了如何使用 堆分析器

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 检查器后端,并接收消息响应和通知。

new inspector.Session()#

创建一个新的 inspector.Session 类实例。检查器会话需要通过 session.connect() 连接,才能将消息分派到检查器后端。

使用 Session 时,除非我们手动执行 Runtime.DiscardConsoleEntries 命令,否则控制台 API 输出的对象不会被释放。

事件:'inspectorNotification'#

当收到来自 V8 检查器的任何通知时发出。

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

警告 使用相同线程会话的断点不推荐,请参阅 断点支持

也可以仅订阅具有特定方法的通知

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

当收到其方法字段设置为<inspector-protocol-method>值的检查器通知时发出。

以下代码片段在 'Debugger.paused' 事件上安装了一个监听器,并在程序执行暂停时(例如通过断点)打印程序暂停的原因

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

警告 使用相同线程会话的断点不推荐,请参阅 断点支持

session.connect()#

将会话连接到检查器后端。

session.connectToMainThread()#

将会话连接到主线程检查器后端。如果此 API 未在 Worker 线程上调用,则会抛出异常。

session.disconnect()#

立即关闭会话。所有挂起的消息回调都将使用错误调用。 session.connect() 需要被调用才能再次发送消息。重新连接的会话将丢失所有检查器状态,例如启用的代理或配置的断点。

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

向检查器后端发布消息。收到响应后会通知 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 协议域提供了一个接口,用于与用于检查应用程序状态和监听运行时事件的运行时代理之一进行交互。

向 V8 发送 HeapProfiler.takeHeapSnapshotHeapProfiler.stopTrackingHeapObjects 命令时,不能将 reportProgress 设置为 true

示例用法#

除了调试器之外,还可以通过 DevTools 协议使用各种 V8 分析器。

CPU 分析器#

以下示例展示了如何使用 CPU 分析器

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));
      }
    });
  });
}); 
堆分析器#

以下示例展示了如何使用 堆分析器

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#

  • <对象> 用于向远程检查器控制台发送消息的对象。
require('node:inspector').console.log('a message'); 

检查器控制台与 Node.js 控制台的 API 不一致。

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

  • port <数字> 用于监听检查器连接的端口。可选。**默认值:**在 CLI 上指定的端口。
  • host <字符串> 用于监听检查器连接的主机。可选。**默认值:**在 CLI 上指定的主机。
  • wait <布尔值> 阻塞直到客户端连接。可选。**默认值:**false
  • 返回值:<Disposable> 一个 Disposable 对象,调用 inspector.close()

在主机和端口上激活检查器。等效于 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://nodejs.ac.cn/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://localhost:3000/51cf8d0e-3c36-4c59-8efd-54519839e56a
For help, see: https://nodejs.ac.cn/en/docs/inspector
ws://localhost:3000/51cf8d0e-3c36-4c59-8efd-54519839e56a

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

inspector.waitForDebugger()#

阻塞直到客户端(现有或稍后连接)发送 Runtime.runIfWaitingForDebugger 命令。

如果不存在活动检查器,则会抛出异常。

断点支持#

Chrome DevTools 协议 Debugger 允许 inspector.Session 附加到程序并设置断点以逐步执行代码。

但是,应避免使用与同一线程连接的 inspector.Session 设置断点,该连接由 session.connect() 建立,因为正在附加和暂停的程序正是调试器本身。 相反,请尝试通过 session.connectToMainThread() 连接到主线程并在工作线程中设置断点,或者通过 WebSocket 连接使用 Debugger 程序进行连接。