进程#

源代码: lib/process.js

process 对象提供有关当前 Node.js 进程的信息并对其进行控制。

import process from 'node:process';const process = require('node:process');

进程事件#

process 对象是 EventEmitter 的一个实例。

事件:'beforeExit'#

当 Node.js 清空其事件循环并且没有额外的工作要调度时,会发出 'beforeExit' 事件。通常,当没有工作被调度时,Node.js 进程将退出,但在 'beforeExit' 事件上注册的监听器可以进行异步调用,从而导致 Node.js 进程继续运行。

监听器回调函数被调用时,会将 process.exitCode 的值作为唯一的参数传入。

对于导致显式终止的条件,例如调用 process.exit() 或未捕获的异常,不会发出 'beforeExit' 事件。

除非意图是调度额外的工作,否则不应'beforeExit' 用作 'exit' 事件的替代方案。

import process from 'node:process';

process.on('beforeExit', (code) => {
  console.log('Process beforeExit event with code: ', code);
});

process.on('exit', (code) => {
  console.log('Process exit event with code: ', code);
});

console.log('This message is displayed first.');

// Prints:
// This message is displayed first.
// Process beforeExit event with code: 0
// Process exit event with code: 0const process = require('node:process');

process.on('beforeExit', (code) => {
  console.log('Process beforeExit event with code: ', code);
});

process.on('exit', (code) => {
  console.log('Process exit event with code: ', code);
});

console.log('This message is displayed first.');

// Prints:
// This message is displayed first.
// Process beforeExit event with code: 0
// Process exit event with code: 0

事件:'disconnect'#

如果 Node.js 进程是使用 IPC 通道衍生的(请参阅子进程集群文档),当 IPC 通道关闭时,将发出 'disconnect' 事件。

事件:'exit'#

当 Node.js 进程因以下任一原因即将退出时,会发出 'exit' 事件:

  • 显式调用了 process.exit() 方法;
  • Node.js 事件循环不再有任何额外的工作要执行。

此时无法阻止事件循环的退出,并且一旦所有 'exit' 监听器运行完毕,Node.js 进程将终止。

监听器回调函数被调用时,会传入由 process.exitCode 属性指定的退出码,或者是传递给 process.exit() 方法的 exitCode 参数。

import process from 'node:process';

process.on('exit', (code) => {
  console.log(`About to exit with code: ${code}`);
});const process = require('node:process');

process.on('exit', (code) => {
  console.log(`About to exit with code: ${code}`);
});

监听器函数必须只执行同步操作。在调用 'exit' 事件监听器后,Node.js 进程将立即退出,导致事件循环中任何仍在排队的额外工作被放弃。例如,在下面的例子中,超时永远不会发生:

import process from 'node:process';

process.on('exit', (code) => {
  setTimeout(() => {
    console.log('This will not run');
  }, 0);
});const process = require('node:process');

process.on('exit', (code) => {
  setTimeout(() => {
    console.log('This will not run');
  }, 0);
});

事件:'message'#

如果 Node.js 进程是使用 IPC 通道衍生的(请参阅子进程集群文档),每当子进程收到由父进程使用 childprocess.send() 发送的消息时,就会发出 'message' 事件。

消息会经过序列化和解析。最终收到的消息可能与最初发送的消息不同。

如果在衍生进程时将 serialization 选项设置为 advanced,那么 message 参数可以包含 JSON 无法表示的数据。更多详情请参阅child_process 的高级序列化

事件:'rejectionHandled'#

  • promise <Promise> 被延迟处理的 Promise。

每当一个 Promise 被拒绝,并且在 Node.js 事件循环的一个轮次之后,有错误处理程序附加到它上面时(例如,使用 promise.catch()),就会发出 'rejectionHandled' 事件。

Promise 对象之前会在 'unhandledRejection' 事件中被发出,但在处理过程中获得了拒绝处理程序。

对于一个 Promise 链来说,没有一个顶层的概念,可以在那里总是处理拒绝。由于其固有的异步性,一个 Promise 的拒绝可以在未来的某个时间点被处理,可能远晚于发出 'unhandledRejection' 事件的那个事件循环轮次。

换句话说,与同步代码中有一个不断增长的未处理异常列表不同,对于 Promises,可能有一个增长和缩小的未处理拒绝列表。

在同步代码中,当未处理异常列表增长时,会发出 'uncaughtException' 事件。

在异步代码中,当未处理拒绝列表增长时,会发出 'unhandledRejection' 事件;当未处理拒绝列表缩小时,会发出 'rejectionHandled' 事件。

import process from 'node:process';

const unhandledRejections = new Map();
process.on('unhandledRejection', (reason, promise) => {
  unhandledRejections.set(promise, reason);
});
process.on('rejectionHandled', (promise) => {
  unhandledRejections.delete(promise);
});const process = require('node:process');

const unhandledRejections = new Map();
process.on('unhandledRejection', (reason, promise) => {
  unhandledRejections.set(promise, reason);
});
process.on('rejectionHandled', (promise) => {
  unhandledRejections.delete(promise);
});

在这个例子中,unhandledRejections Map 会随着时间的推移而增长和缩小,反映了那些开始时未处理,后来被处理的拒绝。可以将这些错误记录在错误日志中,可以定期记录(这对于长期运行的应用程序可能是最好的),也可以在进程退出时记录(这对于脚本来说可能最方便)。

事件:'workerMessage'#

对于另一方使用 postMessageToThread() 发送的任何传入消息,都会发出 'workerMessage' 事件。

事件:'uncaughtException'#

  • err <Error> 未捕获的异常。
  • origin <string> 指示异常是源自未处理的拒绝还是同步错误。可以是 'uncaughtException''unhandledRejection'。当异常发生在基于 Promise 的异步上下文中(或者如果一个 Promise 被拒绝),并且 --unhandled-rejections 标志设置为 strictthrow(这是默认值)且该拒绝未被处理时,或者当拒绝发生在命令行入口点的 ES 模块静态加载阶段时,会使用后者。

当一个未捕获的 JavaScript 异常一直冒泡到事件循环时,会发出 'uncaughtException' 事件。默认情况下,Node.js 通过将堆栈跟踪打印到 stderr 并以代码 1 退出,来处理此类异常,这会覆盖任何先前设置的 process.exitCode。为 'uncaughtException' 事件添加一个处理程序会覆盖此默认行为。或者,在 'uncaughtException' 处理程序中更改 process.exitCode,这将导致进程以提供的退出码退出。否则,在存在此类处理程序的情况下,进程将以 0 退出。

import process from 'node:process';
import fs from 'node:fs';

process.on('uncaughtException', (err, origin) => {
  fs.writeSync(
    process.stderr.fd,
    `Caught exception: ${err}\n` +
    `Exception origin: ${origin}\n`,
  );
});

setTimeout(() => {
  console.log('This will still run.');
}, 500);

// Intentionally cause an exception, but don't catch it.
nonexistentFunc();
console.log('This will not run.');const process = require('node:process');
const fs = require('node:fs');

process.on('uncaughtException', (err, origin) => {
  fs.writeSync(
    process.stderr.fd,
    `Caught exception: ${err}\n` +
    `Exception origin: ${origin}\n`,
  );
});

setTimeout(() => {
  console.log('This will still run.');
}, 500);

// Intentionally cause an exception, but don't catch it.
nonexistentFunc();
console.log('This will not run.');

可以通过安装一个 'uncaughtExceptionMonitor' 监听器来监视 'uncaughtException' 事件,而无需覆盖退出进程的默认行为。

警告:正确使用 'uncaughtException'#

'uncaughtException' 是一种粗糙的异常处理机制,仅应作为最后的手段使用。该事件不应用作 On Error Resume Next 的等价物。未处理的异常本质上意味着应用程序处于未定义状态。在没有从异常中正确恢复的情况下尝试恢复应用程序代码,可能会导致额外的、不可预见和不可预测的问题。

从事件处理程序内部抛出的异常将不会被捕获。相反,进程将以非零退出码退出,并打印堆栈跟踪。这是为了避免无限递归。

在未捕获异常后尝试正常恢复,可能类似于在升级计算机时拔掉电源线。十次中有九次,什么也不会发生。但第十次,系统会损坏。

'uncaughtException' 的正确用法是在关闭进程之前对已分配的资源(例如文件描述符、句柄等)进行同步清理。'uncaughtException' 之后恢复正常操作是不安全的。

要以更可靠的方式重新启动崩溃的应用程序,无论是否发出 'uncaughtException',都应在单独的进程中使用外部监视器来检测应用程序故障并根据需要进行恢复或重新启动。

事件:'uncaughtExceptionMonitor'#

  • err <Error> 未捕获的异常。
  • origin <string> 指示异常是源于未处理的拒绝还是同步错误。可以是 'uncaughtException''unhandledRejection'。当异常发生在基于 Promise 的异步上下文中(或者如果一个 Promise 被拒绝),并且 --unhandled-rejections 标志设置为 strictthrow(这是默认值)且该拒绝未被处理时,或者当拒绝发生在命令行入口点的 ES 模块静态加载阶段时,会使用后者。

'uncaughtExceptionMonitor' 事件在发出 'uncaughtException' 事件或调用通过 process.setUncaughtExceptionCaptureCallback() 安装的钩子之前发出。

安装一个 'uncaughtExceptionMonitor' 监听器并不会改变 'uncaughtException' 事件被触发后的行为。如果没有安装 'uncaughtException' 监听器,进程仍然会崩溃。

import process from 'node:process';

process.on('uncaughtExceptionMonitor', (err, origin) => {
  MyMonitoringTool.logSync(err, origin);
});

// Intentionally cause an exception, but don't catch it.
nonexistentFunc();
// Still crashes Node.jsconst process = require('node:process');

process.on('uncaughtExceptionMonitor', (err, origin) => {
  MyMonitoringTool.logSync(err, origin);
});

// Intentionally cause an exception, but don't catch it.
nonexistentFunc();
// Still crashes Node.js

事件:'unhandledRejection'#

  • reason <Error> | <any> Promise 被拒绝时所使用的对象(通常是一个 Error 对象)。
  • promise <Promise> 被拒绝的 Promise。

当一个 Promise 被拒绝,并且在事件循环的一个轮次内没有错误处理程序附加到该 Promise 上时,就会发出 'unhandledRejection' 事件。在使用 Promise 编程时,异常被封装为“被拒绝的 Promise”。拒绝可以通过 promise.catch() 来捕获和处理,并在 Promise 链中传播。'unhandledRejection' 事件对于检测和跟踪那些被拒绝但其拒绝尚未被处理的 Promise 非常有用。

import process from 'node:process';

process.on('unhandledRejection', (reason, promise) => {
  console.log('Unhandled Rejection at:', promise, 'reason:', reason);
  // Application specific logging, throwing an error, or other logic here
});

somePromise.then((res) => {
  return reportToUser(JSON.pasre(res)); // Note the typo (`pasre`)
}); // No `.catch()` or `.then()`const process = require('node:process');

process.on('unhandledRejection', (reason, promise) => {
  console.log('Unhandled Rejection at:', promise, 'reason:', reason);
  // Application specific logging, throwing an error, or other logic here
});

somePromise.then((res) => {
  return reportToUser(JSON.pasre(res)); // Note the typo (`pasre`)
}); // No `.catch()` or `.then()`

以下情况也会触发 'unhandledRejection' 事件的发出:

import process from 'node:process';

function SomeResource() {
  // Initially set the loaded status to a rejected promise
  this.loaded = Promise.reject(new Error('Resource not yet loaded!'));
}

const resource = new SomeResource();
// no .catch or .then on resource.loaded for at least a turnconst process = require('node:process');

function SomeResource() {
  // Initially set the loaded status to a rejected promise
  this.loaded = Promise.reject(new Error('Resource not yet loaded!'));
}

const resource = new SomeResource();
// no .catch or .then on resource.loaded for at least a turn

在这种示例情况下,可以像对待其他 'unhandledRejection' 事件一样,将此拒绝追踪为开发者错误。为了解决此类失败,可以向 resource.loaded 附加一个无操作的 .catch(() => { }) 处理程序,这将阻止 'unhandledRejection' 事件的发出。

如果发出一个 'unhandledRejection' 事件但未被处理,它将被提升为一个未捕获的异常。这个行为以及 'unhandledRejection' 事件的其他行为可以通过 --unhandled-rejections 标志来更改。

事件:'warning'#

  • warning <Error> 警告的关键属性是:
    • name <string> 警告的名称。默认: 'Warning'
    • message <string> 系统提供的警告描述。
    • stack <string> 指向代码中发出警告位置的堆栈跟踪。

每当 Node.js 发出进程警告时,就会发出 'warning' 事件。

进程警告与错误类似,它描述了提请用户注意的异常情况。然而,警告不属于正常的 Node.js 和 JavaScript 错误处理流程。当 Node.js 检测到可能导致应用程序性能不佳、错误或安全漏洞的不良编码实践时,可以发出警告。

import process from 'node:process';

process.on('warning', (warning) => {
  console.warn(warning.name);    // Print the warning name
  console.warn(warning.message); // Print the warning message
  console.warn(warning.stack);   // Print the stack trace
});const process = require('node:process');

process.on('warning', (warning) => {
  console.warn(warning.name);    // Print the warning name
  console.warn(warning.message); // Print the warning message
  console.warn(warning.stack);   // Print the stack trace
});

默认情况下,Node.js 会将进程警告打印到 stderr。可以使用 --no-warnings 命令行选项来抑制默认的控制台输出,但 process 对象仍然会发出 'warning' 事件。目前,除了弃用警告之外,无法抑制特定类型的警告。要抑制弃用警告,请查看 --no-deprecation 标志。

以下示例说明了当向一个事件添加了过多监听器时,打印到 stderr 的警告:

$ node
> events.defaultMaxListeners = 1;
> process.on('foo', () => {});
> process.on('foo', () => {});
> (node:38638) MaxListenersExceededWarning: Possible EventEmitter memory leak
detected. 2 foo listeners added. Use emitter.setMaxListeners() to increase limit 

相比之下,以下示例关闭了默认的警告输出,并向 'warning' 事件添加了一个自定义处理程序:

$ node --no-warnings
> const p = process.on('warning', (warning) => console.warn('Do not do that!'));
> events.defaultMaxListeners = 1;
> process.on('foo', () => {});
> process.on('foo', () => {});
> Do not do that! 

可以使用 --trace-warnings 命令行选项,使警告的默认控制台输出包含警告的完整堆栈跟踪。

使用 --throw-deprecation 命令行标志启动 Node.js 将导致自定义的弃用警告被作为异常抛出。

使用 --trace-deprecation 命令行标志将导致自定义的弃用信息连同堆栈跟踪一起打印到 stderr

使用 --no-deprecation 命令行标志将抑制所有关于自定义弃用的报告。

*-deprecation 命令行标志仅影响使用名称 'DeprecationWarning' 的警告。

发出自定义警告#

请参阅 process.emitWarning() 方法来发布自定义或特定于应用程序的警告。

Node.js 警告名称#

对于 Node.js 发出的警告类型(由 name 属性标识)没有严格的指导方针。新的警告类型可以随时添加。一些最常见的警告类型包括:

  • 'DeprecationWarning' - 表示使用了已弃用的 Node.js API 或功能。此类警告必须包含一个 'code' 属性,以标识弃用代码
  • 'ExperimentalWarning' - 表示使用了实验性的 Node.js API 或功能。使用这些功能时必须谨慎,因为它们可能随时更改,并且不受与受支持功能相同的严格语义版本控制和长期支持策略的约束。
  • 'MaxListenersExceededWarning' - 表示在 EventEmitterEventTarget 上为给定事件注册了过多的监听器。这通常是内存泄漏的迹象。
  • 'TimeoutOverflowWarning' - 表示向 setTimeout()setInterval() 函数提供了一个无法容纳在 32 位有符号整数中的数值。
  • 'TimeoutNegativeWarning' - 表示向 setTimeout()setInterval() 函数提供了负数。
  • 'TimeoutNaNWarning' - 表示向 setTimeout()setInterval() 函数提供了非数字值。
  • 'UnsupportedWarning' - 表示使用了不受支持的选项或功能,该选项或功能将被忽略而不是被视为错误。一个例子是在使用 HTTP/2 兼容性 API 时使用 HTTP 响应状态消息。

事件:'worker'#

在创建新的 <Worker> 线程后,会发出 'worker' 事件。

信号事件#

当 Node.js 进程接收到信号时,将发出信号事件。请参阅 signal(7) 以获取标准 POSIX 信号名称的列表,例如 'SIGINT''SIGHUP' 等。

信号在 Worker 线程中不可用。

信号处理程序将接收信号的名称('SIGINT''SIGTERM' 等)作为第一个参数。

每个事件的名称将是信号的大写通用名称(例如,SIGINT 信号的 'SIGINT')。

import process from 'node:process';

// Begin reading from stdin so the process does not exit.
process.stdin.resume();

process.on('SIGINT', () => {
  console.log('Received SIGINT. Press Control-D to exit.');
});

// Using a single function to handle multiple signals
function handle(signal) {
  console.log(`Received ${signal}`);
}

process.on('SIGINT', handle);
process.on('SIGTERM', handle);const process = require('node:process');

// Begin reading from stdin so the process does not exit.
process.stdin.resume();

process.on('SIGINT', () => {
  console.log('Received SIGINT. Press Control-D to exit.');
});

// Using a single function to handle multiple signals
function handle(signal) {
  console.log(`Received ${signal}`);
}

process.on('SIGINT', handle);
process.on('SIGTERM', handle);
  • 'SIGUSR1' 由 Node.js 保留用于启动调试器。可以安装监听器,但这样做可能会干扰调试器。
  • 在非 Windows 平台上,'SIGTERM''SIGINT' 有默认处理程序,它们会在退出前重置终端模式,退出码为 128 + 信号编号。如果为这些信号之一安装了监听器,其默认行为将被移除(Node.js 将不再退出)。
  • 'SIGPIPE' 默认被忽略。可以为其安装监听器。
  • 'SIGHUP' 在 Windows 上关闭控制台窗口时生成,在其他平台上则在各种类似条件下生成。请参阅 signal(7)。可以为其安装监听器,但是大约 10 秒后 Node.js 将被 Windows 无条件终止。在非 Windows 平台上,SIGHUP 的默认行为是终止 Node.js,但一旦安装了监听器,其默认行为将被移除。
  • Windows 不支持 'SIGTERM',但可以监听它。
  • 来自终端的 'SIGINT' 在所有平台上都受支持,通常可以通过 Ctrl+C 生成(尽管这可能是可配置的)。当启用终端原始模式并使用 Ctrl+C 时,不会生成该信号。
  • 在 Windows 上按下 Ctrl+Break 时会发送 'SIGBREAK'。在非 Windows 平台上,可以监听它,但没有办法发送或生成它。
  • 当控制台大小调整时,会发送 'SIGWINCH'。在 Windows 上,这只会在向控制台写入、光标移动时,或者当可读 tty 在原始模式下使用时发生。
  • 'SIGKILL' 不能安装监听器,它会在所有平台上无条件终止 Node.js。
  • 'SIGSTOP' 不能安装监听器。
  • 'SIGBUS''SIGFPE''SIGSEGV''SIGILL',当不是通过 kill(2) 人为引发时,本质上会将进程置于一个不安全的状态,无法调用 JS 监听器。这样做可能会导致进程停止响应。
  • 可以发送 0 来测试进程是否存在,如果进程存在则没有效果,但如果进程不存在则会抛出错误。

Windows 不支持信号,因此没有与通过信号终止等效的操作,但 Node.js 通过 process.kill()subprocess.kill() 提供了一些模拟功能。

  • 发送 SIGINTSIGTERMSIGKILL 将导致目标进程无条件终止,之后,子进程将报告该进程被信号终止。
  • 发送信号 0 可以作为一种平台无关的方式来测试进程是否存在。

process.abort()#

process.abort() 方法会使 Node.js 进程立即退出并生成一个核心文件。

此功能在 Worker 线程中不可用。

process.allowedNodeEnvironmentFlags#

process.allowedNodeEnvironmentFlags 属性是一个特殊的、只读的 Set,包含了在 NODE_OPTIONS 环境变量中允许的标志。

process.allowedNodeEnvironmentFlags 扩展了 Set,但重写了 Set.prototype.has 以识别几种不同的可能标志表示形式。在以下情况下,process.allowedNodeEnvironmentFlags.has() 将返回 true

  • 标志可以省略前导的单个(-)或双(--)破折号;例如,inspect-brk 代表 --inspect-brk,或 r 代表 -r
  • 传递给 V8 的标志(如 --v8-options 中所列)可以将一个或多个非前导的破折号替换为下划线,反之亦然;例如,--perf_basic_prof--perf-basic-prof--perf_basic-prof 等。
  • 标志可以包含一个或多个等号(=)字符;第一个等号及其之后的所有字符都将被忽略;例如,--stack-trace-limit=100
  • 标志必须NODE_OPTIONS 中是允许的。

当迭代 process.allowedNodeEnvironmentFlags 时,标志将只出现一次;每个标志都将以一个或多个破折号开头。传递给 V8 的标志将包含下划线而不是非前导的破折号:

import { allowedNodeEnvironmentFlags } from 'node:process';

allowedNodeEnvironmentFlags.forEach((flag) => {
  // -r
  // --inspect-brk
  // --abort_on_uncaught_exception
  // ...
});const { allowedNodeEnvironmentFlags } = require('node:process');

allowedNodeEnvironmentFlags.forEach((flag) => {
  // -r
  // --inspect-brk
  // --abort_on_uncaught_exception
  // ...
});

process.allowedNodeEnvironmentFlagsadd()clear()delete() 方法什么也不做,并且会静默失败。

如果 Node.js 编译时没有 NODE_OPTIONS 支持(显示在 process.config 中),process.allowedNodeEnvironmentFlags 将包含本应允许的内容。

process.arch#

Node.js 二进制文件编译时所针对的操作系统 CPU 架构。可能的值有:'arm''arm64''ia32''loong64''mips''mipsel''ppc64''riscv64''s390''s390x''x64'

import { arch } from 'node:process';

console.log(`This processor architecture is ${arch}`);const { arch } = require('node:process');

console.log(`This processor architecture is ${arch}`);

process.argv#

process.argv 属性返回一个数组,其中包含启动 Node.js 进程时传递的命令行参数。第一个元素将是 process.execPath。如果需要访问 argv[0] 的原始值,请参见 process.argv0。第二个元素将是正在执行的 JavaScript 文件的路径。其余元素将是任何额外的命令行参数。

例如,假设有以下脚本 process-args.js

import { argv } from 'node:process';

// print process.argv
argv.forEach((val, index) => {
  console.log(`${index}: ${val}`);
});const { argv } = require('node:process');

// print process.argv
argv.forEach((val, index) => {
  console.log(`${index}: ${val}`);
});

像这样启动 Node.js 进程:

node process-args.js one two=three four 

将会生成输出:

0: /usr/local/bin/node
1: /Users/mjr/work/node/process-args.js
2: one
3: two=three
4: four 

process.argv0#

process.argv0 属性存储了 Node.js 启动时传递的 argv[0] 原始值的只读副本。

$ bash -c 'exec -a customArgv0 ./node'
> process.argv[0]
'/Volumes/code/external/node/out/Release/node'
> process.argv0
'customArgv0' 

process.availableMemory()#

获取进程仍然可用的空闲内存量(以字节为单位)。

更多信息请参阅 uv_get_available_memory

process.channel#

如果 Node.js 进程是使用 IPC 通道衍生的(参见子进程文档),process.channel 属性是对 IPC 通道的引用。如果不存在 IPC 通道,此属性为 undefined

process.channel.ref()#

如果之前调用过 .unref(),此方法会使 IPC 通道保持进程的事件循环运行。

通常,这是通过 process 对象上的 'disconnect''message' 监听器数量来管理的。但是,可以使用此方法来明确请求特定行为。

process.channel.unref()#

此方法使 IPC 通道不保持进程的事件循环运行,并允许其在通道仍然打开的情况下完成。

通常,这是通过 process 对象上的 'disconnect''message' 监听器数量来管理的。但是,可以使用此方法来明确请求特定行为。

process.chdir(directory)#

process.chdir() 方法更改 Node.js 进程的当前工作目录,如果操作失败(例如,如果指定的 directory 不存在),则抛出异常。

import { chdir, cwd } from 'node:process';

console.log(`Starting directory: ${cwd()}`);
try {
  chdir('/tmp');
  console.log(`New directory: ${cwd()}`);
} catch (err) {
  console.error(`chdir: ${err}`);
}const { chdir, cwd } = require('node:process');

console.log(`Starting directory: ${cwd()}`);
try {
  chdir('/tmp');
  console.log(`New directory: ${cwd()}`);
} catch (err) {
  console.error(`chdir: ${err}`);
}

此功能在 Worker 线程中不可用。

process.config#

process.config 属性返回一个冻结的 Object,其中包含用于编译当前 Node.js 可执行文件的配置选项的 JavaScript 表示。这与运行 ./configure 脚本时生成的 config.gypi 文件相同。

可能的输出示例如下:

{
  target_defaults:
   { cflags: [],
     default_configuration: 'Release',
     defines: [],
     include_dirs: [],
     libraries: [] },
  variables:
   {
     host_arch: 'x64',
     napi_build_version: 5,
     node_install_npm: 'true',
     node_prefix: '',
     node_shared_cares: 'false',
     node_shared_http_parser: 'false',
     node_shared_libuv: 'false',
     node_shared_zlib: 'false',
     node_use_openssl: 'true',
     node_shared_openssl: 'false',
     target_arch: 'x64',
     v8_use_snapshot: 1
   }
} 

process.connected#

如果 Node.js 进程是使用 IPC 通道衍生的(请参阅子进程集群文档),只要 IPC 通道连接着,process.connected 属性将返回 true,在调用 process.disconnect() 后将返回 false

一旦 process.connected 变为 false,就不能再通过 IPC 通道使用 process.send() 发送消息了。

process.constrainedMemory()#

根据操作系统施加的限制,获取进程可用的内存量(以字节为单位)。如果没有这样的约束,或者约束未知,则返回 0

更多信息请参阅 uv_get_constrained_memory

process.cpuUsage([previousValue])#

process.cpuUsage() 方法返回当前进程的用户和系统 CPU 时间使用情况,形式为一个包含 usersystem 属性的对象,其值为微秒值(百万分之一秒)。这些值分别测量在用户代码和系统代码中花费的时间,如果多个 CPU 核心为此进程工作,最终可能会大于实际经过的时间。

可以将上一次调用 process.cpuUsage() 的结果作为参数传递给该函数,以获得一个差异读数。

import { cpuUsage } from 'node:process';

const startUsage = cpuUsage();
// { user: 38579, system: 6986 }

// spin the CPU for 500 milliseconds
const now = Date.now();
while (Date.now() - now < 500);

console.log(cpuUsage(startUsage));
// { user: 514883, system: 11226 }const { cpuUsage } = require('node:process');

const startUsage = cpuUsage();
// { user: 38579, system: 6986 }

// spin the CPU for 500 milliseconds
const now = Date.now();
while (Date.now() - now < 500);

console.log(cpuUsage(startUsage));
// { user: 514883, system: 11226 }

process.cwd()#

process.cwd() 方法返回 Node.js 进程的当前工作目录。

import { cwd } from 'node:process';

console.log(`Current directory: ${cwd()}`);const { cwd } = require('node:process');

console.log(`Current directory: ${cwd()}`);

process.debugPort#

Node.js 调试器启用时使用的端口。

import process from 'node:process';

process.debugPort = 5858;const process = require('node:process');

process.debugPort = 5858;

process.disconnect()#

如果 Node.js 进程是使用 IPC 通道衍生的(请参阅子进程集群文档),process.disconnect() 方法将关闭到父进程的 IPC 通道,从而允许子进程在没有其他连接使其保持活动状态时优雅地退出。

调用 process.disconnect() 的效果与从父进程调用 ChildProcess.disconnect() 相同。

如果 Node.js 进程不是使用 IPC 通道衍生的,process.disconnect() 将是 undefined

process.dlopen(module, filename[, flags])#

process.dlopen() 方法允许动态加载共享对象。它主要由 require() 用于加载 C++ 插件,并且除非在特殊情况下,否则不应直接使用。换句话说,除非有特定原因,例如自定义 dlopen 标志或从 ES 模块加载,否则应首选 require() 而不是 process.dlopen()

flags 参数是一个整数,允许指定 dlopen 的行为。有关详细信息,请参阅 os.constants.dlopen 文档。

调用 process.dlopen() 的一个重要要求是必须传递 module 实例。然后,C++ 插件导出的函数可以通过 module.exports 访问。

下面的示例展示了如何加载一个名为 local.node 的 C++ 插件,该插件导出一个 foo 函数。通过传递 RTLD_NOW 常量,所有符号在调用返回之前被加载。在这个例子中,假设该常量是可用的。

import { dlopen } from 'node:process';
import { constants } from 'node:os';
import { fileURLToPath } from 'node:url';

const module = { exports: {} };
dlopen(module, fileURLToPath(new URL('local.node', import.meta.url)),
       constants.dlopen.RTLD_NOW);
module.exports.foo();const { dlopen } = require('node:process');
const { constants } = require('node:os');
const { join } = require('node:path');

const module = { exports: {} };
dlopen(module, join(__dirname, 'local.node'), constants.dlopen.RTLD_NOW);
module.exports.foo();

process.emitWarning(warning[, options])#

  • warning <string> | <Error> 要发出的警告。
  • options <Object>
    • type <string>warningString 时,type 是用于发出的警告类型的名称。默认: 'Warning'
    • code <string> 正在发出的警告实例的唯一标识符。
    • ctor <Function>warningString 时,ctor 是一个可选函数,用于限制生成的堆栈跟踪。默认: process.emitWarning
    • detail <string> 与错误一起包含的附加文本。

process.emitWarning() 方法可用于发出自定义或特定于应用程序的进程警告。可以通过向 'warning' 事件添加处理程序来监听这些警告。

import { emitWarning } from 'node:process';

// Emit a warning with a code and additional detail.
emitWarning('Something happened!', {
  code: 'MY_WARNING',
  detail: 'This is some additional information',
});
// Emits:
// (node:56338) [MY_WARNING] Warning: Something happened!
// This is some additional informationconst { emitWarning } = require('node:process');

// Emit a warning with a code and additional detail.
emitWarning('Something happened!', {
  code: 'MY_WARNING',
  detail: 'This is some additional information',
});
// Emits:
// (node:56338) [MY_WARNING] Warning: Something happened!
// This is some additional information

在这个例子中,process.emitWarning() 内部生成一个 Error 对象,并将其传递给 'warning' 处理程序。

import process from 'node:process';

process.on('warning', (warning) => {
  console.warn(warning.name);    // 'Warning'
  console.warn(warning.message); // 'Something happened!'
  console.warn(warning.code);    // 'MY_WARNING'
  console.warn(warning.stack);   // Stack trace
  console.warn(warning.detail);  // 'This is some additional information'
});const process = require('node:process');

process.on('warning', (warning) => {
  console.warn(warning.name);    // 'Warning'
  console.warn(warning.message); // 'Something happened!'
  console.warn(warning.code);    // 'MY_WARNING'
  console.warn(warning.stack);   // Stack trace
  console.warn(warning.detail);  // 'This is some additional information'
});

如果 warning 作为 Error 对象传递,options 参数将被忽略。

process.emitWarning(warning[, type[, code]][, ctor])#

  • warning <string> | <Error> 要发出的警告。
  • type <string>warningString 时,type 是用于发出的警告类型的名称。默认: 'Warning'
  • code <string> 正在发出的警告实例的唯一标识符。
  • ctor <Function>warningString 时,ctor 是一个可选函数,用于限制生成的堆栈跟踪。默认: process.emitWarning

process.emitWarning() 方法可用于发出自定义或特定于应用程序的进程警告。可以通过向 'warning' 事件添加处理程序来监听这些警告。

import { emitWarning } from 'node:process';

// Emit a warning using a string.
emitWarning('Something happened!');
// Emits: (node: 56338) Warning: Something happened!const { emitWarning } = require('node:process');

// Emit a warning using a string.
emitWarning('Something happened!');
// Emits: (node: 56338) Warning: Something happened!
import { emitWarning } from 'node:process';

// Emit a warning using a string and a type.
emitWarning('Something Happened!', 'CustomWarning');
// Emits: (node:56338) CustomWarning: Something Happened!const { emitWarning } = require('node:process');

// Emit a warning using a string and a type.
emitWarning('Something Happened!', 'CustomWarning');
// Emits: (node:56338) CustomWarning: Something Happened!
import { emitWarning } from 'node:process';

emitWarning('Something happened!', 'CustomWarning', 'WARN001');
// Emits: (node:56338) [WARN001] CustomWarning: Something happened!const { emitWarning } = require('node:process');

process.emitWarning('Something happened!', 'CustomWarning', 'WARN001');
// Emits: (node:56338) [WARN001] CustomWarning: Something happened!

在前面的每个例子中,process.emitWarning() 内部都会生成一个 Error 对象,并将其传递给 'warning' 处理程序。

import process from 'node:process';

process.on('warning', (warning) => {
  console.warn(warning.name);
  console.warn(warning.message);
  console.warn(warning.code);
  console.warn(warning.stack);
});const process = require('node:process');

process.on('warning', (warning) => {
  console.warn(warning.name);
  console.warn(warning.message);
  console.warn(warning.code);
  console.warn(warning.stack);
});

如果 warning 是作为 Error 对象传递的,它将被原封不动地传递给 'warning' 事件处理程序(并且可选的 typecodector 参数将被忽略):

import { emitWarning } from 'node:process';

// Emit a warning using an Error object.
const myWarning = new Error('Something happened!');
// Use the Error name property to specify the type name
myWarning.name = 'CustomWarning';
myWarning.code = 'WARN001';

emitWarning(myWarning);
// Emits: (node:56338) [WARN001] CustomWarning: Something happened!const { emitWarning } = require('node:process');

// Emit a warning using an Error object.
const myWarning = new Error('Something happened!');
// Use the Error name property to specify the type name
myWarning.name = 'CustomWarning';
myWarning.code = 'WARN001';

emitWarning(myWarning);
// Emits: (node:56338) [WARN001] CustomWarning: Something happened!

如果 warning 是除了字符串或 Error 对象之外的任何东西,则会抛出 TypeError

虽然进程警告使用 Error 对象,但进程警告机制并不是正常错误处理机制的替代品。

如果警告 type'DeprecationWarning',则会实现以下附加处理:

  • 如果使用了 --throw-deprecation 命令行标志,弃用警告将被作为异常抛出,而不是作为事件发出。
  • 如果使用了 --no-deprecation 命令行标志,弃用警告将被抑制。
  • 如果使用了 --trace-deprecation 命令行标志,弃用警告将与完整的堆栈跟踪一起打印到 stderr

避免重复的警告#

作为最佳实践,警告每个进程只应发出一次。为此,可以将 emitWarning() 放在一个布尔值后面。

import { emitWarning } from 'node:process';

function emitMyWarning() {
  if (!emitMyWarning.warned) {
    emitMyWarning.warned = true;
    emitWarning('Only warn once!');
  }
}
emitMyWarning();
// Emits: (node: 56339) Warning: Only warn once!
emitMyWarning();
// Emits nothingconst { emitWarning } = require('node:process');

function emitMyWarning() {
  if (!emitMyWarning.warned) {
    emitMyWarning.warned = true;
    emitWarning('Only warn once!');
  }
}
emitMyWarning();
// Emits: (node: 56339) Warning: Only warn once!
emitMyWarning();
// Emits nothing

process.env#

process.env 属性返回一个包含用户环境的对象。参见 environ(7)

该对象的一个示例如下:

{
  TERM: 'xterm-256color',
  SHELL: '/usr/local/bin/bash',
  USER: 'maciej',
  PATH: '~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin',
  PWD: '/Users/maciej',
  EDITOR: 'vim',
  SHLVL: '1',
  HOME: '/Users/maciej',
  LOGNAME: 'maciej',
  _: '/usr/local/bin/node'
} 

可以修改这个对象,但这些修改不会反映到 Node.js 进程之外,或者(除非明确请求)反映到其他 Worker 线程。换句话说,以下示例将不起作用:

node -e 'process.env.foo = "bar"' && echo $foo 

而以下示例则可以:

import { env } from 'node:process';

env.foo = 'bar';
console.log(env.foo);const { env } = require('node:process');

env.foo = 'bar';
console.log(env.foo);

process.env 上分配属性将隐式地将值转换为字符串。此行为已被弃用。未来版本的 Node.js 在值不是字符串、数字或布尔值时可能会抛出错误。

import { env } from 'node:process';

env.test = null;
console.log(env.test);
// => 'null'
env.test = undefined;
console.log(env.test);
// => 'undefined'const { env } = require('node:process');

env.test = null;
console.log(env.test);
// => 'null'
env.test = undefined;
console.log(env.test);
// => 'undefined'

使用 deleteprocess.env 中删除属性。

import { env } from 'node:process';

env.TEST = 1;
delete env.TEST;
console.log(env.TEST);
// => undefinedconst { env } = require('node:process');

env.TEST = 1;
delete env.TEST;
console.log(env.TEST);
// => undefined

在 Windows 操作系统上,环境变量不区分大小写。

import { env } from 'node:process';

env.TEST = 1;
console.log(env.test);
// => 1const { env } = require('node:process');

env.TEST = 1;
console.log(env.test);
// => 1

除非在创建 Worker 实例时明确指定,否则每个 Worker 线程都有其自己的 process.env 副本,该副本基于其父线程的 process.env,或者基于为 Worker 构造函数指定的 env 选项。对 process.env 的更改在 Worker 线程之间不可见,只有主线程可以进行对操作系统或原生插件可见的更改。在 Windows 上,Worker 实例上的 process.env 副本以区分大小写的方式操作,这与主线程不同。

process.execArgv#

process.execArgv 属性返回在启动 Node.js 进程时传递的一组特定于 Node.js 的命令行选项。这些选项不会出现在 process.argv 属性返回的数组中,并且不包括 Node.js 可执行文件、脚本名称或脚本名称之后的任何选项。这些选项对于以与父进程相同的执行环境衍生子进程非常有用。

node --icu-data-dir=./foo --require ./bar.js script.js --version 

process.execArgv 的结果:

["--icu-data-dir=./foo", "--require", "./bar.js"] 

以及 process.argv 的结果:

['/usr/local/bin/node', 'script.js', '--version'] 

有关此属性在工作线程中的详细行为,请参阅 Worker 构造函数

process.execPath#

process.execPath 属性返回启动 Node.js 进程的可执行文件的绝对路径名。符号链接(如果有)会被解析。

'/usr/local/bin/node' 

process.execve(file[, args[, env]])#

稳定性:1 - 实验性

  • file <string> 要运行的可执行文件的名称或路径。
  • args <string[]> 字符串参数列表。任何参数都不能包含空字节(\u0000)。
  • env <Object> 环境变量键值对。任何键或值都不能包含空字节(\u0000)。默认: process.env

用新进程替换当前进程。

这是通过使用 execve POSIX 函数实现的,因此除了标准输入、标准输出和标准错误文件描述符外,当前进程的内存或其他资源都不会被保留。

所有其他资源在进程交换时都会被系统丢弃,不会触发任何退出或关闭事件,也不会运行任何清理处理程序。

除非发生错误,否则此函数永远不会返回。

此函数在 Windows 或 IBM i 上不可用。

process.exit([code])#

process.exit() 方法指示 Node.js 以 code 的退出状态同步终止进程。如果省略 code,则退出使用“成功”代码 0process.exitCode 的值(如果已设置)。Node.js 在所有 'exit' 事件监听器被调用之前不会终止。

以“失败”代码退出:

import { exit } from 'node:process';

exit(1);const { exit } = require('node:process');

exit(1);

执行 Node.js 的 shell 应该看到退出码为 1

调用 process.exit() 将强制进程尽快退出,即使仍有尚未完全完成的异步操作在等待,包括对 process.stdoutprocess.stderr 的 I/O 操作。

在大多数情况下,实际上没有必要显式调用 process.exit()。如果事件循环中没有额外的待处理工作,Node.js 进程将自行退出。可以设置 process.exitCode 属性来告诉进程在正常退出时使用哪个退出码。

例如,下面的例子说明了对 process.exit() 方法的误用,这可能导致打印到 stdout 的数据被截断和丢失:

import { exit } from 'node:process';

// This is an example of what *not* to do:
if (someConditionNotMet()) {
  printUsageToStdout();
  exit(1);
}const { exit } = require('node:process');

// This is an example of what *not* to do:
if (someConditionNotMet()) {
  printUsageToStdout();
  exit(1);
}

这个问题的原因在于,在 Node.js 中对 process.stdout 的写入有时是异步的,并且可能在 Node.js 事件循环的多个轮次中发生。然而,调用 process.exit() 会强制进程在这些额外的 stdout 写入操作执行之前退出。

与其直接调用 process.exit(),代码应该设置 process.exitCode 并允许进程自然退出,方法是避免为事件循环调度任何额外的工作:

import process from 'node:process';

// How to properly set the exit code while letting
// the process exit gracefully.
if (someConditionNotMet()) {
  printUsageToStdout();
  process.exitCode = 1;
}const process = require('node:process');

// How to properly set the exit code while letting
// the process exit gracefully.
if (someConditionNotMet()) {
  printUsageToStdout();
  process.exitCode = 1;
}

如果由于错误条件需要终止 Node.js 进程,抛出一个未捕获的错误并允许进程相应地终止,比调用 process.exit() 更安全。

Worker 线程中,此函数会停止当前线程而不是当前进程。

process.exitCode#

当进程正常退出,或者通过 process.exit() 退出而未指定代码时,将作为进程退出码的数字。

process.exitCode 的值可以通过给 process.exitCode 赋值或通过向 process.exit() 传递参数来更新:

$ node -e 'process.exitCode = 9'; echo $?
9
$ node -e 'process.exit(42)'; echo $?
42
$ node -e 'process.exitCode = 9; process.exit(42)'; echo $?
42 

当发生不可恢复的错误时(例如遇到未解决的顶层 await),Node.js 也会隐式设置该值。然而,对退出码的显式操作总是优先于隐式操作:

$ node --input-type=module -e 'await new Promise(() => {})'; echo $?
13
$ node --input-type=module -e 'process.exitCode = 9; await new Promise(() => {})'; echo $?
9 

process.features.cached_builtins#

一个布尔值,如果当前的 Node.js 构建正在缓存内置模块,则为 true

process.features.debug#

一个布尔值,如果当前的 Node.js 构建是调试构建,则为 true

process.features.inspector#

一个布尔值,如果当前的 Node.js 构建包含检查器,则为 true

process.features.ipv6#

稳定性:0 - 已弃用。此属性始终为 true,任何基于它的检查都是多余的。

一个布尔值,如果当前的 Node.js 构建包含对 IPv6 的支持,则为 true

由于所有 Node.js 构建都支持 IPv6,因此该值始终为 true

process.features.require_module#

一个布尔值,如果当前的 Node.js 构建支持使用 require() 加载 ECMAScript 模块,则为 true

process.features.tls#

一个布尔值,如果当前的 Node.js 构建包含对 TLS 的支持,则为 true

process.features.tls_alpn#

稳定性:0 - 已弃用。请改用 process.features.tls

一个布尔值,如果当前的 Node.js 构建包含对 TLS 中 ALPN 的支持,则为 true

在 Node.js 11.0.0 及更高版本中,OpenSSL 依赖项具有无条件的 ALPN 支持。因此,该值与 process.features.tls 的值相同。

process.features.tls_ocsp#

稳定性:0 - 已弃用。请改用 process.features.tls

一个布尔值,如果当前的 Node.js 构建包含对 TLS 中 OCSP 的支持,则为 true

在 Node.js 11.0.0 及更高版本中,OpenSSL 依赖项具有无条件的 OCSP 支持。因此,该值与 process.features.tls 的值相同。

process.features.tls_sni#

稳定性:0 - 已弃用。请改用 process.features.tls

一个布尔值,如果当前的 Node.js 构建包含对 TLS 中 SNI 的支持,则为 true

在 Node.js 11.0.0 及更高版本中,OpenSSL 依赖项具有无条件的 SNI 支持。因此,该值与 process.features.tls 的值相同。

process.features.typescript#

稳定性:1.2 - 候选发布

一个值,默认情况下为 "strip",如果 Node.js 使用 --experimental-transform-types 运行,则为 "transform",如果 Node.js 使用 --no-experimental-strip-types 运行,则为 false

process.features.uv#

稳定性:0 - 已弃用。此属性始终为 true,任何基于它的检查都是多余的。

一个布尔值,如果当前的 Node.js 构建包含对 libuv 的支持,则为 true

由于不可能在没有 libuv 的情况下构建 Node.js,因此该值始终为 true

process.finalization.register(ref, callback)#

稳定性:1.1 - 活跃开发

此函数注册一个回调,如果 ref 对象未被垃圾回收,当进程发出 exit 事件时将被调用。如果 ref 对象在发出 exit 事件之前被垃圾回收,回调将从终结注册表中移除,并且在进程退出时不会被调用。

在回调函数内部,您可以释放由 ref 对象分配的资源。请注意,应用于 beforeExit 事件的所有限制也适用于 callback 函数,这意味着在特殊情况下,回调可能不会被调用。

这个函数的想法是帮助您在进程开始退出时释放资源,但如果对象不再被使用,也让其被垃圾回收。

例如:您可以注册一个包含缓冲区的对象,您想确保在进程退出时该缓冲区被释放,但如果该对象在进程退出前被垃圾回收,我们就不再需要释放该缓冲区了,所以在这种情况下,我们只需从终结注册表中移除回调即可。

const { finalization } = require('node:process');

// Please make sure that the function passed to finalization.register()
// does not create a closure around unnecessary objects.
function onFinalize(obj, event) {
  // You can do whatever you want with the object
  obj.dispose();
}

function setup() {
  // This object can be safely garbage collected,
  // and the resulting shutdown function will not be called.
  // There are no leaks.
  const myDisposableObject = {
    dispose() {
      // Free your resources synchronously
    },
  };

  finalization.register(myDisposableObject, onFinalize);
}

setup();import { finalization } from 'node:process';

// Please make sure that the function passed to finalization.register()
// does not create a closure around unnecessary objects.
function onFinalize(obj, event) {
  // You can do whatever you want with the object
  obj.dispose();
}

function setup() {
  // This object can be safely garbage collected,
  // and the resulting shutdown function will not be called.
  // There are no leaks.
  const myDisposableObject = {
    dispose() {
      // Free your resources synchronously
    },
  };

  finalization.register(myDisposableObject, onFinalize);
}

setup();

上面的代码依赖于以下假设:

  • 避免使用箭头函数
  • 建议常规函数在全局上下文(根)内

常规函数可能引用 obj 所在的上下文,导致 obj 无法被垃圾回收。

箭头函数将持有先前的上下文。例如,考虑:

class Test {
  constructor() {
    finalization.register(this, (ref) => ref.dispose());

    // Even something like this is highly discouraged
    // finalization.register(this, () => this.dispose());
  }
  dispose() {}
} 

这个对象被垃圾回收的可能性很小(但不是不可能),但如果它没有被垃圾回收,dispose 将在调用 process.exit 时被调用。

请小心,避免依赖此功能来处理关键资源的释放,因为不保证在所有情况下都会调用回调。

process.finalization.registerBeforeExit(ref, callback)#

稳定性:1.1 - 活跃开发

此函数的行为与 register 完全相同,只是如果 ref 对象未被垃圾回收,当进程发出 beforeExit 事件时,回调将被调用。

请注意,应用于 beforeExit 事件的所有限制也适用于 callback 函数,这意味着在特殊情况下,回调可能不会被调用。

process.finalization.unregister(ref)#

稳定性:1.1 - 活跃开发

此函数从终结注册表中移除对象的注册,因此回调将不再被调用。

const { finalization } = require('node:process');

// Please make sure that the function passed to finalization.register()
// does not create a closure around unnecessary objects.
function onFinalize(obj, event) {
  // You can do whatever you want with the object
  obj.dispose();
}

function setup() {
  // This object can be safely garbage collected,
  // and the resulting shutdown function will not be called.
  // There are no leaks.
  const myDisposableObject = {
    dispose() {
      // Free your resources synchronously
    },
  };

  finalization.register(myDisposableObject, onFinalize);

  // Do something

  myDisposableObject.dispose();
  finalization.unregister(myDisposableObject);
}

setup();import { finalization } from 'node:process';

// Please make sure that the function passed to finalization.register()
// does not create a closure around unnecessary objects.
function onFinalize(obj, event) {
  // You can do whatever you want with the object
  obj.dispose();
}

function setup() {
  // This object can be safely garbage collected,
  // and the resulting shutdown function will not be called.
  // There are no leaks.
  const myDisposableObject = {
    dispose() {
      // Free your resources synchronously
    },
  };

  // Please make sure that the function passed to finalization.register()
  // does not create a closure around unnecessary objects.
  function onFinalize(obj, event) {
    // You can do whatever you want with the object
    obj.dispose();
  }

  finalization.register(myDisposableObject, onFinalize);

  // Do something

  myDisposableObject.dispose();
  finalization.unregister(myDisposableObject);
}

setup();

process.getActiveResourcesInfo()#

process.getActiveResourcesInfo() 方法返回一个字符串数组,其中包含当前使事件循环保持活动的活动资源的类型。

import { getActiveResourcesInfo } from 'node:process';
import { setTimeout } from 'node:timers';

console.log('Before:', getActiveResourcesInfo());
setTimeout(() => {}, 1000);
console.log('After:', getActiveResourcesInfo());
// Prints:
//   Before: [ 'CloseReq', 'TTYWrap', 'TTYWrap', 'TTYWrap' ]
//   After: [ 'CloseReq', 'TTYWrap', 'TTYWrap', 'TTYWrap', 'Timeout' ]const { getActiveResourcesInfo } = require('node:process');
const { setTimeout } = require('node:timers');

console.log('Before:', getActiveResourcesInfo());
setTimeout(() => {}, 1000);
console.log('After:', getActiveResourcesInfo());
// Prints:
//   Before: [ 'TTYWrap', 'TTYWrap', 'TTYWrap' ]
//   After: [ 'TTYWrap', 'TTYWrap', 'TTYWrap', 'Timeout' ]

process.getBuiltinModule(id)#

process.getBuiltinModule(id) 提供了一种在全局可用函数中加载内置模块的方法。需要支持其他环境的 ES 模块可以使用它在 Node.js 中运行时有条件地加载 Node.js 内置模块,而无需处理在非 Node.js 环境中 import 可能抛出的解析错误,也无需使用动态 import(),后者要么将模块变成异步模块,要么将同步 API 变成异步 API。

if (globalThis.process?.getBuiltinModule) {
  // Run in Node.js, use the Node.js fs module.
  const fs = globalThis.process.getBuiltinModule('fs');
  // If `require()` is needed to load user-modules, use createRequire()
  const module = globalThis.process.getBuiltinModule('module');
  const require = module.createRequire(import.meta.url);
  const foo = require('foo');
} 

如果 id 指定了当前 Node.js 进程中可用的内置模块,process.getBuiltinModule(id) 方法将返回相应的内置模块。如果 id 不对应任何内置模块,则返回 undefined

process.getBuiltinModule(id) 接受 module.isBuiltin(id) 识别的内置模块 ID。一些内置模块必须使用 node: 前缀加载,请参阅具有强制性 node: 前缀的内置模块。即使使用者修改了 require.cache 使得 require(id) 返回其他内容,process.getBuiltinModule(id) 返回的引用也总是指向与 id 对应的内置模块。

process.getegid()#

process.getegid() 方法返回 Node.js 进程的数字有效组标识。(参见 getegid(2).)

import process from 'node:process';

if (process.getegid) {
  console.log(`Current gid: ${process.getegid()}`);
}const process = require('node:process');

if (process.getegid) {
  console.log(`Current gid: ${process.getegid()}`);
}

此功能仅在 POSIX 平台(即非 Windows 或 Android)上可用。

process.geteuid()#

process.geteuid() 方法返回进程的数字有效用户身份。(参见 geteuid(2).)

import process from 'node:process';

if (process.geteuid) {
  console.log(`Current uid: ${process.geteuid()}`);
}const process = require('node:process');

if (process.geteuid) {
  console.log(`Current uid: ${process.geteuid()}`);
}

此功能仅在 POSIX 平台(即非 Windows 或 Android)上可用。

process.getgid()#

process.getgid() 方法返回进程的数字组标识。(参见 getgid(2).)

import process from 'node:process';

if (process.getgid) {
  console.log(`Current gid: ${process.getgid()}`);
}const process = require('node:process');

if (process.getgid) {
  console.log(`Current gid: ${process.getgid()}`);
}

此功能仅在 POSIX 平台(即非 Windows 或 Android)上可用。

process.getgroups()#

process.getgroups() 方法返回一个包含补充组 ID 的数组。POSIX 未指定是否包含有效组 ID,但 Node.js 确保始终包含。

import process from 'node:process';

if (process.getgroups) {
  console.log(process.getgroups()); // [ 16, 21, 297 ]
}const process = require('node:process');

if (process.getgroups) {
  console.log(process.getgroups()); // [ 16, 21, 297 ]
}

此功能仅在 POSIX 平台(即非 Windows 或 Android)上可用。

process.getuid()#

process.getuid() 方法返回进程的数字用户身份。(参见 getuid(2).)

import process from 'node:process';

if (process.getuid) {
  console.log(`Current uid: ${process.getuid()}`);
}const process = require('node:process');

if (process.getuid) {
  console.log(`Current uid: ${process.getuid()}`);
}

此功能在 Windows 上不可用。

process.hasUncaughtExceptionCaptureCallback()#

指示是否已使用 process.setUncaughtExceptionCaptureCallback() 设置了回调。

process.hrtime([time])#

稳定性:3 - 遗留。请改用 process.hrtime.bigint()

这是在 JavaScript 中引入 bigint 之前 process.hrtime.bigint() 的旧版。

process.hrtime() 方法以 [秒, 纳秒] 元组 Array 的形式返回当前的高精度实时时间,其中 nanoseconds 是无法以秒精度表示的实时时间的剩余部分。

time 是一个可选参数,必须是上一次 process.hrtime() 调用的结果,用于与当前时间进行比较。如果传入的参数不是一个元组 Array,将会抛出 TypeError。传入用户定义的数组而不是上一次 process.hrtime() 调用的结果,将导致未定义的行为。

这些时间是相对于过去的某个任意时间点,与一天中的时间无关,因此不受时钟漂移的影响。其主要用途是测量时间间隔之间的性能。

import { hrtime } from 'node:process';

const NS_PER_SEC = 1e9;
const time = hrtime();
// [ 1800216, 25 ]

setTimeout(() => {
  const diff = hrtime(time);
  // [ 1, 552 ]

  console.log(`Benchmark took ${diff[0] * NS_PER_SEC + diff[1]} nanoseconds`);
  // Benchmark took 1000000552 nanoseconds
}, 1000);const { hrtime } = require('node:process');

const NS_PER_SEC = 1e9;
const time = hrtime();
// [ 1800216, 25 ]

setTimeout(() => {
  const diff = hrtime(time);
  // [ 1, 552 ]

  console.log(`Benchmark took ${diff[0] * NS_PER_SEC + diff[1]} nanoseconds`);
  // Benchmark took 1000000552 nanoseconds
}, 1000);

process.hrtime.bigint()#

process.hrtime() 方法的 bigint 版本,以 bigint 形式返回当前的高精度实时时间(单位为纳秒)。

process.hrtime() 不同,它不支持额外的 time 参数,因为可以直接通过两个 bigint 相减来计算差值。

import { hrtime } from 'node:process';

const start = hrtime.bigint();
// 191051479007711n

setTimeout(() => {
  const end = hrtime.bigint();
  // 191052633396993n

  console.log(`Benchmark took ${end - start} nanoseconds`);
  // Benchmark took 1154389282 nanoseconds
}, 1000);const { hrtime } = require('node:process');

const start = hrtime.bigint();
// 191051479007711n

setTimeout(() => {
  const end = hrtime.bigint();
  // 191052633396993n

  console.log(`Benchmark took ${end - start} nanoseconds`);
  // Benchmark took 1154389282 nanoseconds
}, 1000);

process.initgroups(user, extraGroup)#

process.initgroups() 方法读取 /etc/group 文件并初始化组访问列表,使用该用户所属的所有组。这是一个特权操作,要求 Node.js 进程具有 root 访问权限或 CAP_SETGID 能力。

在放弃权限时要小心。

import { getgroups, initgroups, setgid } from 'node:process';

console.log(getgroups());         // [ 0 ]
initgroups('nodeuser', 1000);     // switch user
console.log(getgroups());         // [ 27, 30, 46, 1000, 0 ]
setgid(1000);                     // drop root gid
console.log(getgroups());         // [ 27, 30, 46, 1000 ]const { getgroups, initgroups, setgid } = require('node:process');

console.log(getgroups());         // [ 0 ]
initgroups('nodeuser', 1000);     // switch user
console.log(getgroups());         // [ 27, 30, 46, 1000, 0 ]
setgid(1000);                     // drop root gid
console.log(getgroups());         // [ 27, 30, 46, 1000 ]

此函数仅在 POSIX 平台(即非 Windows 或 Android)上可用。此功能在 Worker 线程中不可用。

process.kill(pid[, signal])#

  • pid <number> 进程 ID
  • signal <string> | <number> 要发送的信号,可以是字符串或数字。默认值: 'SIGTERM'

process.kill() 方法将 signal 发送给由 pid 标识的进程。

信号名称是诸如 'SIGINT''SIGHUP' 之类的字符串。有关更多信息,请参见信号事件kill(2)

如果目标 pid 不存在,此方法将抛出错误。作为特例,信号 0 可用于测试进程是否存在。在 Windows 平台上,如果使用 pid 来终止一个进程组,将会抛出错误。

尽管此函数的名称是 process.kill(),但它实际上只是一个信号发送器,就像 kill 系统调用一样。发送的信号可能执行的操作不只是终止目标进程。

import process, { kill } from 'node:process';

process.on('SIGHUP', () => {
  console.log('Got SIGHUP signal.');
});

setTimeout(() => {
  console.log('Exiting.');
  process.exit(0);
}, 100);

kill(process.pid, 'SIGHUP');const process = require('node:process');

process.on('SIGHUP', () => {
  console.log('Got SIGHUP signal.');
});

setTimeout(() => {
  console.log('Exiting.');
  process.exit(0);
}, 100);

process.kill(process.pid, 'SIGHUP');

当 Node.js 进程接收到 SIGUSR1 时,Node.js 将启动调试器。请参见信号事件

process.loadEnvFile(path)#

.env 文件加载到 process.env 中。在 .env 文件中使用 NODE_OPTIONS 对 Node.js 不会产生任何影响。

const { loadEnvFile } = require('node:process');
loadEnvFile();import { loadEnvFile } from 'node:process';
loadEnvFile();

process.mainModule#

稳定性:0 - 已弃用:请改用 require.main

process.mainModule 属性提供了另一种检索 require.main 的方法。区别在于,如果主模块在运行时发生变化,require.main 在那些变化发生前被引入的模块中,可能仍然指向原始的主模块。通常可以安全地假设两者指向同一个模块。

require.main 一样,如果没有入口脚本,process.mainModule 将为 undefined

process.memoryUsage()#

返回一个描述 Node.js 进程内存使用情况的对象,单位为字节。

import { memoryUsage } from 'node:process';

console.log(memoryUsage());
// Prints:
// {
//  rss: 4935680,
//  heapTotal: 1826816,
//  heapUsed: 650472,
//  external: 49879,
//  arrayBuffers: 9386
// }const { memoryUsage } = require('node:process');

console.log(memoryUsage());
// Prints:
// {
//  rss: 4935680,
//  heapTotal: 1826816,
//  heapUsed: 650472,
//  external: 49879,
//  arrayBuffers: 9386
// }
  • heapTotalheapUsed 指的是 V8 的内存使用情况。
  • external 指的是绑定到由 V8 管理的 JavaScript 对象的 C++ 对象的内存使用情况。
  • rss,即驻留集大小(Resident Set Size),是进程在主内存设备中占用的空间量(是总分配内存的子集),包括所有 C++ 和 JavaScript 对象及代码。
  • arrayBuffers 指的是为 ArrayBufferSharedArrayBuffer 分配的内存,包括所有的 Node.js Buffer。这部分也包含在 external 值中。当 Node.js 作为嵌入式库使用时,此值可能为 0,因为在这种情况下可能不会跟踪 ArrayBuffer 的分配。

当使用 Worker 线程时,rss 将是适用于整个进程的值,而其他字段仅指当前线程。

process.memoryUsage() 方法会遍历每个页面以收集有关内存使用的信息,这可能会根据程序的内存分配情况而变慢。

关于 process.memoryUsage 的注意事项#

在 Linux 或其他通常使用 glibc 的系统上,尽管 heapTotal 稳定,但由于 glibc malloc 实现引起的碎片化,应用程序可能会出现持续的 rss 增长。请参见 nodejs/node#21973 了解如何切换到备用 malloc 实现以解决此性能问题。

process.memoryUsage.rss()#

process.memoryUsage.rss() 方法返回一个表示驻留集大小(RSS)的整数,单位为字节。

驻留集大小是进程在主内存设备中占用的空间量(是总分配内存的子集),包括所有 C++ 和 JavaScript 对象及代码。

这与 process.memoryUsage() 提供的 rss 属性的值相同,但 process.memoryUsage.rss() 更快。

import { memoryUsage } from 'node:process';

console.log(memoryUsage.rss());
// 35655680const { memoryUsage } = require('node:process');

console.log(memoryUsage.rss());
// 35655680

process.nextTick(callback[, ...args])#

稳定性:3 - 遗留:请改用 queueMicrotask()

  • callback <Function>
  • ...args <any> 调用 callback 时传递的额外参数。

process.nextTick()callback 添加到“next tick 队列”。此队列在 JavaScript 栈上的当前操作运行完成后、事件循环被允许继续之前完全清空。如果递归调用 process.nextTick(),可能会创建一个无限循环。有关更多背景信息,请参见事件循环指南。

import { nextTick } from 'node:process';

console.log('start');
nextTick(() => {
  console.log('nextTick callback');
});
console.log('scheduled');
// Output:
// start
// scheduled
// nextTick callbackconst { nextTick } = require('node:process');

console.log('start');
nextTick(() => {
  console.log('nextTick callback');
});
console.log('scheduled');
// Output:
// start
// scheduled
// nextTick callback

这在开发 API 时非常重要,以便在对象被构造之后、任何 I/O 发生之前,给用户机会分配事件处理程序。

import { nextTick } from 'node:process';

function MyThing(options) {
  this.setupOptions(options);

  nextTick(() => {
    this.startDoingStuff();
  });
}

const thing = new MyThing();
thing.getReadyForStuff();

// thing.startDoingStuff() gets called now, not before.const { nextTick } = require('node:process');

function MyThing(options) {
  this.setupOptions(options);

  nextTick(() => {
    this.startDoingStuff();
  });
}

const thing = new MyThing();
thing.getReadyForStuff();

// thing.startDoingStuff() gets called now, not before.

对于 API 来说,要么 100% 同步,要么 100% 异步,这是非常重要的。考虑这个例子:

// WARNING!  DO NOT USE!  BAD UNSAFE HAZARD!
function maybeSync(arg, cb) {
  if (arg) {
    cb();
    return;
  }

  fs.stat('file', cb);
} 

这个 API 是危险的,因为在以下情况下:

const maybeTrue = Math.random() > 0.5;

maybeSync(maybeTrue, () => {
  foo();
});

bar(); 

不清楚是 foo() 还是 bar() 会先被调用。

以下方法要好得多:

import { nextTick } from 'node:process';

function definitelyAsync(arg, cb) {
  if (arg) {
    nextTick(cb);
    return;
  }

  fs.stat('file', cb);
}const { nextTick } = require('node:process');

function definitelyAsync(arg, cb) {
  if (arg) {
    nextTick(cb);
    return;
  }

  fs.stat('file', cb);
}

何时使用 queueMicrotask()process.nextTick()#

queueMicrotask() API 是 process.nextTick() 的一个替代方案,它不使用“next tick 队列”,而是使用与执行已解析 promise 的 then、catch 和 finally 处理程序相同的微任务队列来延迟函数的执行。

在 Node.js 内部,每当“next tick 队列”被清空时,微任务队列会紧接着被清空。

因此,在 CJS 模块中,process.nextTick() 回调总是在 queueMicrotask() 回调之前运行。然而,由于 ESM 模块本身就是作为微任务队列的一部分处理的,因此在 ESM 模块中,queueMicrotask() 回调总是在 process.nextTick() 回调之前执行,因为此时 Node.js 已经在处理微任务队列。

import { nextTick } from 'node:process';

Promise.resolve().then(() => console.log('resolve'));
queueMicrotask(() => console.log('microtask'));
nextTick(() => console.log('nextTick'));
// Output:
// resolve
// microtask
// nextTickconst { nextTick } = require('node:process');

Promise.resolve().then(() => console.log('resolve'));
queueMicrotask(() => console.log('microtask'));
nextTick(() => console.log('nextTick'));
// Output:
// nextTick
// resolve
// microtask

对于大多数用户空间的用例,queueMicrotask() API 提供了一种可移植且可靠的延迟执行机制,它在多个 JavaScript 平台环境中都有效,应优先于 process.nextTick() 使用。在简单场景中,queueMicrotask() 可以作为 process.nextTick() 的直接替代品。

console.log('start');
queueMicrotask(() => {
  console.log('microtask callback');
});
console.log('scheduled');
// Output:
// start
// scheduled
// microtask callback 

这两个 API 之间一个值得注意的区别是,process.nextTick() 允许指定额外的参数,这些参数将在调用延迟函数时作为参数传递。要用 queueMicrotask() 实现同样的效果,需要使用闭包或绑定函数:

function deferred(a, b) {
  console.log('microtask', a + b);
}

console.log('start');
queueMicrotask(deferred.bind(undefined, 1, 2));
console.log('scheduled');
// Output:
// start
// scheduled
// microtask 3 

在处理从 next tick 队列和微任务队列内部抛出的错误方面存在细微差异。在排队的微任务回调中抛出的错误应尽可能在该回调内部处理。如果未能处理,可以使用 process.on('uncaughtException') 事件处理程序来捕获和处理这些错误。

如有疑问,除非需要 process.nextTick() 的特定功能,否则请使用 queueMicrotask()

process.noDeprecation#

process.noDeprecation 属性指示当前 Node.js 进程是否设置了 --no-deprecation 标志。有关此标志行为的更多信息,请参阅 'warning' 事件emitWarning() 方法的文档。

process.permission#

此 API 可通过 --permission 标志使用。

process.permission 是一个对象,其方法用于管理当前进程的权限。更多文档可在权限模型中找到。

process.permission.has(scope[, reference])#

验证进程是否能够访问给定的范围和引用。如果未提供引用,则假定为全局范围,例如,process.permission.has('fs.read') 将检查进程是否拥有所有文件系统的读取权限。

引用(reference)的含义基于提供的范围(scope)。例如,当范围是文件系统时,引用指的是文件和文件夹。

可用的范围有:

  • fs - 所有文件系统
  • fs.read - 文件系统读取操作
  • fs.write - 文件系统写入操作
  • child - 子进程生成操作
  • worker - 工作线程生成操作
// Check if the process has permission to read the README file
process.permission.has('fs.read', './README.md');
// Check if the process has read permission operations
process.permission.has('fs.read'); 

process.pid#

process.pid 属性返回进程的 PID。

import { pid } from 'node:process';

console.log(`This process is pid ${pid}`);const { pid } = require('node:process');

console.log(`This process is pid ${pid}`);

process.platform#

process.platform 属性返回一个字符串,标识编译 Node.js 二进制文件时所针对的操作系统平台。

当前可能的值有:

  • 'aix'
  • 'darwin'
  • 'freebsd'
  • 'linux'
  • 'openbsd'
  • 'sunos'
  • 'win32'
import { platform } from 'node:process';

console.log(`This platform is ${platform}`);const { platform } = require('node:process');

console.log(`This platform is ${platform}`);

如果 Node.js 是在 Android 操作系统上构建的,也可能返回值 'android'。然而,Node.js 对 Android 的支持是实验性的

process.ppid#

process.ppid 属性返回当前进程的父进程的 PID。

import { ppid } from 'node:process';

console.log(`The parent process is pid ${ppid}`);const { ppid } = require('node:process');

console.log(`The parent process is pid ${ppid}`);

process.ref(maybeRefable)#

稳定性:1 - 实验性

  • maybeRefable <any> 一个可能是“可引用”的对象。

一个对象是“可引用的”,如果它实现了 Node.js 的“Refable 协议”。具体来说,这意味着该对象实现了 Symbol.for('nodejs.ref')Symbol.for('nodejs.unref') 方法。被“引用”(Ref'd)的对象将使 Node.js 事件循环保持活动状态,而被“取消引用”(unref'd)的对象则不会。历史上,这是通过直接在对象上使用 ref()unref() 方法来实现的。然而,这种模式正在被弃用,以支持“Refable 协议”,以便更好地支持 Web 平台 API 类型,这些类型的 API 无法修改以添加 ref()unref() 方法,但仍需支持该行为。

process.release#

process.release 属性返回一个包含与当前发布版本相关的元数据的 Object,包括源码 tarball 和仅头文件的 tarball 的 URL。

process.release 包含以下属性:

  • name <string> 一个始终为 'node' 的值。
  • sourceUrl <string> 一个指向包含当前发布版本源代码的 .tar.gz 文件的绝对 URL。
  • headersUrl<string> 一个指向仅包含当前发布版本源头文件的 .tar.gz 文件的绝对 URL。此文件比完整源文件小得多,可用于编译 Node.js 原生插件。
  • libUrl <string> | <undefined> 一个指向与当前发布版本的架构和版本匹配的 node.lib 文件的绝对 URL。此文件用于编译 Node.js 原生插件。此属性仅存在于 Node.js 的 Windows 构建版本中,在所有其他平台上都将缺失。
  • lts <string> | <undefined> 一个标识此版本 LTS 标签的字符串。此属性仅存在于 LTS 版本中,对于所有其他发布类型(包括当前版本)均为 undefined。有效值包括 LTS 发布代号(包括那些不再受支持的)。
    • 对于从 14.15.0 开始的 14.x LTS 系列,为 'Fermium'
    • 对于从 16.13.0 开始的 16.x LTS 系列,为 'Gallium'
    • 对于从 18.12.0 开始的 18.x LTS 系列,为 'Hydrogen'。对于其他 LTS 发布代号,请参见 Node.js 更新日志归档
{
  name: 'node',
  lts: 'Hydrogen',
  sourceUrl: 'https://node.org.cn/download/release/v18.12.0/node-v18.12.0.tar.gz',
  headersUrl: 'https://node.org.cn/download/release/v18.12.0/node-v18.12.0-headers.tar.gz',
  libUrl: 'https://node.org.cn/download/release/v18.12.0/win-x64/node.lib'
} 

在从非发布版本的源代码树进行的自定义构建中,可能只存在 name 属性。不应依赖其他属性的存在。

process.report#

process.report 是一个对象,其方法用于为当前进程生成诊断报告。更多文档可在报告文档中找到。

process.report.compact#

以紧凑格式写入报告,即单行 JSON,比专为人类阅读设计的默认多行格式更容易被日志处理系统使用。

import { report } from 'node:process';

console.log(`Reports are compact? ${report.compact}`);const { report } = require('node:process');

console.log(`Reports are compact? ${report.compact}`);

process.report.directory#

报告写入的目录。默认值为空字符串,表示报告将写入 Node.js 进程的当前工作目录。

import { report } from 'node:process';

console.log(`Report directory is ${report.directory}`);const { report } = require('node:process');

console.log(`Report directory is ${report.directory}`);

process.report.filename#

报告写入的文件名。如果设置为空字符串,输出文件名将由时间戳、PID 和序列号组成。默认值为空字符串。

如果 process.report.filename 的值设置为 'stdout''stderr',报告将分别写入进程的标准输出或标准错误。

import { report } from 'node:process';

console.log(`Report filename is ${report.filename}`);const { report } = require('node:process');

console.log(`Report filename is ${report.filename}`);

process.report.getReport([err])#

  • err <Error> 一个自定义错误,用于报告 JavaScript 堆栈。
  • 返回:<Object>

返回一个正在运行进程的诊断报告的 JavaScript 对象表示。报告的 JavaScript 堆栈跟踪取自 err(如果存在)。

import { report } from 'node:process';
import util from 'node:util';

const data = report.getReport();
console.log(data.header.nodejsVersion);

// Similar to process.report.writeReport()
import fs from 'node:fs';
fs.writeFileSync('my-report.log', util.inspect(data), 'utf8');const { report } = require('node:process');
const util = require('node:util');

const data = report.getReport();
console.log(data.header.nodejsVersion);

// Similar to process.report.writeReport()
const fs = require('node:fs');
fs.writeFileSync('my-report.log', util.inspect(data), 'utf8');

更多文档可在报告文档中找到。

process.report.reportOnFatalError#

如果为 true,则在发生致命错误时生成诊断报告,例如内存不足错误或失败的 C++ 断言。

import { report } from 'node:process';

console.log(`Report on fatal error: ${report.reportOnFatalError}`);const { report } = require('node:process');

console.log(`Report on fatal error: ${report.reportOnFatalError}`);

process.report.reportOnSignal#

如果为 true,则当进程收到由 process.report.signal 指定的信号时生成诊断报告。

import { report } from 'node:process';

console.log(`Report on signal: ${report.reportOnSignal}`);const { report } = require('node:process');

console.log(`Report on signal: ${report.reportOnSignal}`);

process.report.reportOnUncaughtException#

如果为 true,则在未捕获的异常上生成诊断报告。

import { report } from 'node:process';

console.log(`Report on exception: ${report.reportOnUncaughtException}`);const { report } = require('node:process');

console.log(`Report on exception: ${report.reportOnUncaughtException}`);

process.report.excludeEnv#

如果为 true,则生成的诊断报告中将不包含环境变量。

process.report.signal#

用于触发创建诊断报告的信号。默认为 'SIGUSR2'

import { report } from 'node:process';

console.log(`Report signal: ${report.signal}`);const { report } = require('node:process');

console.log(`Report signal: ${report.signal}`);

process.report.writeReport([filename][, err])#

  • filename <string> 报告写入的文件名。这应该是一个相对路径,它将被附加到 process.report.directory 中指定的目录,如果未指定,则为 Node.js 进程的当前工作目录。

  • err <Error> 一个自定义错误,用于报告 JavaScript 堆栈。

  • 返回: <string> 返回生成的报告的文件名。

将诊断报告写入文件。如果未提供 filename,默认文件名将包括日期、时间、PID 和一个序列号。报告的 JavaScript 堆栈跟踪取自 err(如果存在)。

如果 filename 的值设置为 'stdout''stderr',报告将分别写入进程的标准输出或标准错误。

import { report } from 'node:process';

report.writeReport();const { report } = require('node:process');

report.writeReport();

更多文档可在报告文档中找到。

process.resourceUsage()#

  • 返回:<Object> 当前进程的资源使用情况。所有这些值都来自 uv_getrusage 调用,该调用返回一个 uv_rusage_t 结构
    • userCPUTime <integer> 映射到以微秒计算的 ru_utime。它与 process.cpuUsage().user 的值相同。
    • systemCPUTime <integer> 映射到以微秒计算的 ru_stime。它与 process.cpuUsage().system 的值相同。
    • maxRSS <integer> 映射到 ru_maxrss,这是以 kibibytes (1024 字节) 为单位使用的最大驻留集大小。
    • sharedMemorySize <integer> 映射到 ru_ixrss,但任何平台都不支持。
    • unsharedDataSize <integer> 映射到 ru_idrss,但任何平台都不支持。
    • unsharedStackSize <integer> 映射到 ru_isrss,但任何平台都不支持。
    • minorPageFault <integer> 映射到 ru_minflt,这是进程的次要页面错误的数量,更多详细信息请参阅这篇文章
    • majorPageFault <integer> 映射到 ru_majflt,这是进程的主要页面错误的数量,更多详细信息请参阅这篇文章。此字段在 Windows 上不受支持。
    • swappedOut <integer> 映射到 ru_nswap,但任何平台都不支持。
    • fsRead <integer> 映射到 ru_inblock,这是文件系统必须执行输入的次数。
    • fsWrite <integer> 映射到 ru_oublock,这是文件系统必须执行输出的次数。
    • ipcSent <integer> 映射到 ru_msgsnd,但任何平台都不支持。
    • ipcReceived <integer> 映射到 ru_msgrcv,但任何平台都不支持。
    • signalsCount <integer> 映射到 ru_nsignals,但任何平台都不支持。
    • voluntaryContextSwitches <integer> 映射到 ru_nvcsw,这是由于进程在其时间片完成前自愿放弃处理器(通常是为了等待资源可用)而导致的 CPU 上下文切换次数。此字段在 Windows 上不受支持。
    • involuntaryContextSwitches <integer> 映射到 ru_nivcsw,这是由于更高优先级的进程变为可运行或当前进程超出了其时间片而导致的 CPU 上下文切换次数。此字段在 Windows 上不受支持。
import { resourceUsage } from 'node:process';

console.log(resourceUsage());
/*
  Will output:
  {
    userCPUTime: 82872,
    systemCPUTime: 4143,
    maxRSS: 33164,
    sharedMemorySize: 0,
    unsharedDataSize: 0,
    unsharedStackSize: 0,
    minorPageFault: 2469,
    majorPageFault: 0,
    swappedOut: 0,
    fsRead: 0,
    fsWrite: 8,
    ipcSent: 0,
    ipcReceived: 0,
    signalsCount: 0,
    voluntaryContextSwitches: 79,
    involuntaryContextSwitches: 1
  }
*/const { resourceUsage } = require('node:process');

console.log(resourceUsage());
/*
  Will output:
  {
    userCPUTime: 82872,
    systemCPUTime: 4143,
    maxRSS: 33164,
    sharedMemorySize: 0,
    unsharedDataSize: 0,
    unsharedStackSize: 0,
    minorPageFault: 2469,
    majorPageFault: 0,
    swappedOut: 0,
    fsRead: 0,
    fsWrite: 8,
    ipcSent: 0,
    ipcReceived: 0,
    signalsCount: 0,
    voluntaryContextSwitches: 79,
    involuntaryContextSwitches: 1
  }
*/

process.send(message[, sendHandle[, options]][, callback])#

  • message <Object>
  • sendHandle <net.Server> | <net.Socket>
  • options <Object> 用于参数化发送特定类型的句柄。options 支持以下属性:
    • keepOpen <boolean> 一个可以在传递 net.Socket 实例时使用的值。当为 true 时,套接字在发送进程中保持打开状态。默认值: false
  • callback <Function>
  • 返回:<boolean>

如果 Node.js 是通过 IPC 通道生成的,可以使用 process.send() 方法向父进程发送消息。消息将在父进程的 ChildProcess 对象上作为 'message' 事件接收。

如果 Node.js 不是通过 IPC 通道生成的,process.send 将为 undefined

消息会经过序列化和解析。最终收到的消息可能与最初发送的消息不同。

process.setegid(id)#

process.setegid() 方法设置进程的有效组标识。(参见 setegid(2)。) id 可以作为数字 ID 或组名字符串传递。如果指定了组名,此方法将在解析关联的数字 ID 时阻塞。

import process from 'node:process';

if (process.getegid && process.setegid) {
  console.log(`Current gid: ${process.getegid()}`);
  try {
    process.setegid(501);
    console.log(`New gid: ${process.getegid()}`);
  } catch (err) {
    console.error(`Failed to set gid: ${err}`);
  }
}const process = require('node:process');

if (process.getegid && process.setegid) {
  console.log(`Current gid: ${process.getegid()}`);
  try {
    process.setegid(501);
    console.log(`New gid: ${process.getegid()}`);
  } catch (err) {
    console.error(`Failed to set gid: ${err}`);
  }
}

此函数仅在 POSIX 平台(即非 Windows 或 Android)上可用。此功能在 Worker 线程中不可用。

process.seteuid(id)#

process.seteuid() 方法设置进程的有效用户标识。(参见 seteuid(2)。) id 可以作为数字 ID 或用户名字符串传递。如果指定了用户名,此方法将在解析关联的数字 ID 时阻塞。

import process from 'node:process';

if (process.geteuid && process.seteuid) {
  console.log(`Current uid: ${process.geteuid()}`);
  try {
    process.seteuid(501);
    console.log(`New uid: ${process.geteuid()}`);
  } catch (err) {
    console.error(`Failed to set uid: ${err}`);
  }
}const process = require('node:process');

if (process.geteuid && process.seteuid) {
  console.log(`Current uid: ${process.geteuid()}`);
  try {
    process.seteuid(501);
    console.log(`New uid: ${process.geteuid()}`);
  } catch (err) {
    console.error(`Failed to set uid: ${err}`);
  }
}

此函数仅在 POSIX 平台(即非 Windows 或 Android)上可用。此功能在 Worker 线程中不可用。

process.setgid(id)#

process.setgid() 方法设置进程的组标识。(参见 setgid(2)。) id 可以作为数字 ID 或组名字符串传递。如果指定了组名,此方法将在解析关联的数字 ID 时阻塞。

import process from 'node:process';

if (process.getgid && process.setgid) {
  console.log(`Current gid: ${process.getgid()}`);
  try {
    process.setgid(501);
    console.log(`New gid: ${process.getgid()}`);
  } catch (err) {
    console.error(`Failed to set gid: ${err}`);
  }
}const process = require('node:process');

if (process.getgid && process.setgid) {
  console.log(`Current gid: ${process.getgid()}`);
  try {
    process.setgid(501);
    console.log(`New gid: ${process.getgid()}`);
  } catch (err) {
    console.error(`Failed to set gid: ${err}`);
  }
}

此函数仅在 POSIX 平台(即非 Windows 或 Android)上可用。此功能在 Worker 线程中不可用。

process.setgroups(groups)#

process.setgroups() 方法为 Node.js 进程设置补充组 ID。这是一个特权操作,需要 Node.js 进程具有 root 权限或 CAP_SETGID 能力。

groups 数组可以包含数字组 ID、组名或两者兼有。

import process from 'node:process';

if (process.getgroups && process.setgroups) {
  try {
    process.setgroups([501]);
    console.log(process.getgroups()); // new groups
  } catch (err) {
    console.error(`Failed to set groups: ${err}`);
  }
}const process = require('node:process');

if (process.getgroups && process.setgroups) {
  try {
    process.setgroups([501]);
    console.log(process.getgroups()); // new groups
  } catch (err) {
    console.error(`Failed to set groups: ${err}`);
  }
}

此函数仅在 POSIX 平台(即非 Windows 或 Android)上可用。此功能在 Worker 线程中不可用。

process.setuid(id)#

process.setuid(id) 方法设置进程的用户标识。(参见 setuid(2)。) id 可以作为数字 ID 或用户名字符串传递。如果指定了用户名,此方法将在解析关联的数字 ID 时阻塞。

import process from 'node:process';

if (process.getuid && process.setuid) {
  console.log(`Current uid: ${process.getuid()}`);
  try {
    process.setuid(501);
    console.log(`New uid: ${process.getuid()}`);
  } catch (err) {
    console.error(`Failed to set uid: ${err}`);
  }
}const process = require('node:process');

if (process.getuid && process.setuid) {
  console.log(`Current uid: ${process.getuid()}`);
  try {
    process.setuid(501);
    console.log(`New uid: ${process.getuid()}`);
  } catch (err) {
    console.error(`Failed to set uid: ${err}`);
  }
}

此函数仅在 POSIX 平台(即非 Windows 或 Android)上可用。此功能在 Worker 线程中不可用。

process.setSourceMapsEnabled(val)#

稳定性:1 - 实验性:请改用 module.setSourceMapsSupport()

此函数启用或禁用堆栈跟踪的源映射支持。

它提供了与使用命令行选项 --enable-source-maps 启动 Node.js 进程相同的功能。

只有在启用源映射后加载的 JavaScript 文件中的源映射才会被解析和加载。

这等同于使用选项 { nodeModules: true, generatedCode: true } 调用 module.setSourceMapsSupport()

process.setUncaughtExceptionCaptureCallback(fn)#

process.setUncaughtExceptionCaptureCallback() 函数设置一个在发生未捕获异常时调用的函数,该函数将接收异常值本身作为其第一个参数。

如果设置了这样的函数,'uncaughtException' 事件将不会被触发。如果从命令行传递了 --abort-on-uncaught-exception 或通过 v8.setFlagsFromString() 设置了该选项,进程将不会中止。配置在异常时执行的操作(如生成报告)也会受到影响。

要取消设置捕获函数,可以使用 process.setUncaughtExceptionCaptureCallback(null)。在已设置另一个捕获函数的情况下,使用非 null 参数调用此方法将抛出错误。

使用此函数与使用已弃用的 domain 内置模块是互斥的。

process.sourceMapsEnabled#

稳定性:1 - 实验性:请改用 module.getSourceMapsSupport()

process.sourceMapsEnabled 属性返回堆栈跟踪的源映射支持是否已启用。

process.stderr#

process.stderr 属性返回一个连接到 stderr (fd 2) 的流。它是一个 net.Socket(它是一个双工流),除非 fd 2 指向一个文件,在这种情况下它是一个可写流。

process.stderr 在重要方面与其他 Node.js 流不同。有关更多信息,请参见关于进程 I/O 的说明

process.stderr.fd#

此属性指的是 process.stderr 底层文件描述符的值。该值固定为 2。在 Worker 线程中,此字段不存在。

process.stdin#

process.stdin 属性返回一个连接到 stdin (fd 0) 的流。它是一个 net.Socket(它是一个双工流),除非 fd 0 指向一个文件,在这种情况下它是一个可读流。

有关如何从 stdin 读取的详细信息,请参见 readable.read()

作为一个双工流,process.stdin 也可以在“旧”模式下使用,该模式与为 v0.10 之前的 Node.js 编写的脚本兼容。有关更多信息,请参见流兼容性

在“旧”流模式下,stdin 流默认是暂停的,因此必须调用 process.stdin.resume() 才能从中读取。另请注意,调用 process.stdin.resume() 本身会将流切换到“旧”模式。

process.stdin.fd#

此属性指的是 process.stdin 底层文件描述符的值。该值固定为 0。在 Worker 线程中,此字段不存在。

process.stdout#

process.stdout 属性返回一个连接到 stdout (fd 1) 的流。它是一个 net.Socket(它是一个双工流),除非 fd 1 指向一个文件,在这种情况下它是一个可写流。

例如,要将 process.stdin 复制到 process.stdout

import { stdin, stdout } from 'node:process';

stdin.pipe(stdout);const { stdin, stdout } = require('node:process');

stdin.pipe(stdout);

process.stdout 在重要方面与其他 Node.js 流不同。有关更多信息,请参见关于进程 I/O 的说明

process.stdout.fd#

此属性指的是 process.stdout 底层文件描述符的值。该值固定为 1。在 Worker 线程中,此字段不存在。

关于进程 I/O 的说明#

process.stdoutprocess.stderr 在重要方面与其他 Node.js 流不同:

  1. 它们分别被 console.log()console.error() 内部使用。
  2. 写入可能是同步的,这取决于流连接到什么以及系统是 Windows 还是 POSIX:
    • 文件:在 Windows 和 POSIX 上是同步的
    • TTY(终端):在 Windows 上是异步的,在 POSIX 上是同步的
    • 管道(和套接字):在 Windows 上是同步的,在 POSIX 上是异步的

这些行为部分是由于历史原因,因为更改它们会造成向后不兼容,但一些用户也期望如此。

同步写入避免了诸如使用 console.log()console.error() 写入的输出意外交错,或者如果在异步写入完成前调用 process.exit() 则根本不写入的问题。有关更多信息,请参见 process.exit()

警告:同步写入会阻塞事件循环,直到写入完成。在向文件输出的情况下,这可能几乎是瞬时的,但在高系统负载下,接收端未读取的管道,或者慢速终端或文件系统的情况下,事件循环可能被频繁且长时间地阻塞,从而产生严重的负面性能影响。当写入到交互式终端会话时,这可能不是问题,但在生产环境中将日志记录到进程输出流时,请特别小心考虑这一点。

要检查流是否连接到 TTY 上下文,请检查 isTTY 属性。

例如:

$ node -p "Boolean(process.stdin.isTTY)"
true
$ echo "foo" | node -p "Boolean(process.stdin.isTTY)"
false
$ node -p "Boolean(process.stdout.isTTY)"
true
$ node -p "Boolean(process.stdout.isTTY)" | cat
false 

有关更多信息,请参见 TTY 文档。

process.throwDeprecation#

process.throwDeprecation 的初始值表示当前 Node.js 进程是否设置了 --throw-deprecation 标志。process.throwDeprecation 是可变的,因此是否弃用警告会导致错误可以在运行时更改。有关更多信息,请参阅 'warning' 事件emitWarning() 方法的文档。

$ node --throw-deprecation -p "process.throwDeprecation"
true
$ node -p "process.throwDeprecation"
undefined
$ node
> process.emitWarning('test', 'DeprecationWarning');
undefined
> (node:26598) DeprecationWarning: test
> process.throwDeprecation = true;
true
> process.emitWarning('test', 'DeprecationWarning');
Thrown:
[DeprecationWarning: test] { name: 'DeprecationWarning' } 

process.threadCpuUsage([previousValue])#

process.threadCpuUsage() 方法返回当前工作线程的用户和系统 CPU 时间使用情况,以一个包含 usersystem 属性的对象形式返回,其值为微秒值(百万分之一秒)。

可以将上一次调用 process.threadCpuUsage() 的结果作为参数传递给该函数,以获得差异读数。

process.title#

process.title 属性返回当前进程的标题(即返回 ps 的当前值)。为 process.title 赋一个新值会修改 ps 的当前值。

当分配新值时,不同平台会对标题施加不同的最大长度限制。通常这些限制相当有限。例如,在 Linux 和 macOS 上,process.title 受限于二进制文件名加上命令行参数的长度,因为设置 process.title 会覆盖进程的 argv 内存。Node.js v0.8 允许更长的进程标题字符串,因为它也覆盖了 environ 内存,但这在某些(相当晦涩的)情况下可能不安全且令人困惑。

process.title 赋值可能不会在进程管理器应用程序(如 macOS 的活动监视器或 Windows 的服务管理器)中产生准确的标签。

process.traceDeprecation#

process.traceDeprecation 属性指示当前 Node.js 进程是否设置了 --trace-deprecation 标志。有关此标志行为的更多信息,请参阅 'warning' 事件emitWarning() 方法的文档。

process.umask()#

稳定性:0 - 已弃用。不带参数调用 process.umask() 会导致进程范围的 umask 被写入两次。这会在线程之间引入竞争条件,并且是一个潜在的安全漏洞。没有安全的、跨平台的替代 API。

process.umask() 返回 Node.js 进程的文件模式创建掩码。子进程从父进程继承掩码。

process.umask(mask)#

process.umask(mask) 设置 Node.js 进程的文件模式创建掩码。子进程从父进程继承掩码。返回先前的掩码。

import { umask } from 'node:process';

const newmask = 0o022;
const oldmask = umask(newmask);
console.log(
  `Changed umask from ${oldmask.toString(8)} to ${newmask.toString(8)}`,
);const { umask } = require('node:process');

const newmask = 0o022;
const oldmask = umask(newmask);
console.log(
  `Changed umask from ${oldmask.toString(8)} to ${newmask.toString(8)}`,
);

Worker 线程中,process.umask(mask) 将会抛出异常。

process.unref(maybeRefable)#

稳定性:1 - 实验性

  • maybeUnfefable <any> 一个可能是“可取消引用”的对象。

一个对象是“可取消引用的”,如果它实现了 Node.js 的“Refable 协议”。具体来说,这意味着该对象实现了 Symbol.for('nodejs.ref')Symbol.for('nodejs.unref') 方法。被“引用”(Ref'd)的对象将使 Node.js 事件循环保持活动状态,而被“取消引用”(unref'd)的对象则不会。历史上,这是通过直接在对象上使用 ref()unref() 方法来实现的。然而,这种模式正在被弃用,以支持“Refable 协议”,以便更好地支持 Web 平台 API 类型,这些类型的 API 无法修改以添加 ref()unref() 方法,但仍需支持该行为。

process.uptime()#

process.uptime() 方法返回当前 Node.js 进程已运行的秒数。

返回值包括秒的小数部分。使用 Math.floor() 来获取整数秒。

process.version#

process.version 属性包含 Node.js 版本字符串。

import { version } from 'node:process';

console.log(`Version: ${version}`);
// Version: v14.8.0const { version } = require('node:process');

console.log(`Version: ${version}`);
// Version: v14.8.0

要获取不带前缀 v 的版本字符串,请使用 process.versions.node

process.versions#

process.versions 属性返回一个列出 Node.js 及其依赖项版本字符串的对象。process.versions.modules 表示当前的 ABI 版本,每当 C++ API 发生变化时,该版本就会增加。Node.js 将拒绝加载针对不同模块 ABI 版本编译的模块。

import { versions } from 'node:process';

console.log(versions);const { versions } = require('node:process');

console.log(versions);

将生成一个类似于以下内容的对象:

{ node: '23.0.0',
  acorn: '8.11.3',
  ada: '2.7.8',
  ares: '1.28.1',
  base64: '0.5.2',
  brotli: '1.1.0',
  cjs_module_lexer: '1.2.2',
  cldr: '45.0',
  icu: '75.1',
  llhttp: '9.2.1',
  modules: '127',
  napi: '9',
  nghttp2: '1.61.0',
  nghttp3: '0.7.0',
  ngtcp2: '1.3.0',
  openssl: '3.0.13+quic',
  simdjson: '3.8.0',
  simdutf: '5.2.4',
  sqlite: '3.46.0',
  tz: '2024a',
  undici: '6.13.0',
  unicode: '15.1',
  uv: '1.48.0',
  uvwasi: '0.0.20',
  v8: '12.4.254.14-node.11',
  zlib: '1.3.0.1-motley-7d77fb7' } 

退出码#

当没有更多异步操作待处理时,Node.js 通常会以状态码 0 退出。在其他情况下使用以下状态码:

  • 1 未捕获的致命异常:存在一个未捕获的异常,并且它没有被域(domain)或 'uncaughtException' 事件处理程序处理。
  • 2: 未使用(由 Bash 为内置命令误用保留)
  • 3 内部 JavaScript 解析错误:Node.js 引导过程中的内部 JavaScript 源代码导致了解析错误。这种情况极为罕见,通常只可能在 Node.js 本身的开发过程中发生。
  • 4 内部 JavaScript 评估失败:Node.js 引导过程中的内部 JavaScript 源代码在评估时未能返回一个函数值。这种情况极为罕见,通常只可能在 Node.js 本身的开发过程中发生。
  • 5 致命错误:V8 中存在一个致命的不可恢复错误。通常会向 stderr 打印一条带有前缀 FATAL ERROR 的消息。
  • 6 非函数的内部异常处理程序:存在一个未捕获的异常,但内部致命异常处理函数由于某种原因被设置为非函数,无法被调用。
  • 7 内部异常处理程序运行时失败:存在一个未捕获的异常,并且内部致命异常处理函数本身在尝试处理它时抛出了一个错误。例如,当一个 'uncaughtException'domain.on('error') 处理程序抛出错误时,可能会发生这种情况。
  • 8: 未使用。在 Node.js 的早期版本中,退出码 8 有时表示未捕获的异常。
  • 9 无效参数:指定了一个未知的选项,或者一个需要值的选项没有提供值。
  • 10 内部 JavaScript 运行时失败:Node.js 引导过程中的内部 JavaScript 源代码在调用引导函数时抛出了一个错误。这种情况极为罕见,通常只可能在 Node.js 本身的开发过程中发生。
  • 12 无效的调试参数:设置了 --inspect 和/或 --inspect-brk 选项,但选择的端口号无效或不可用。
  • 13 未解决的顶层 Await:在顶层代码中函数之外使用了 await,但传递的 Promise 从未解决。
  • 14 快照失败:Node.js 启动以构建 V8 启动快照,但由于应用程序状态的某些要求未得到满足而失败。
  • >128 信号退出:如果 Node.js 收到一个致命信号,如 SIGKILLSIGHUP,那么它的退出码将是 128 加上信号码的值。这是一种标准的 POSIX 实践,因为退出码被定义为 7 位整数,而信号退出会设置高位,然后包含信号码的值。例如,信号 SIGABRT 的值为 6,因此预期的退出码将是 128 + 6,即 134