process 是什么?
process 是 Node.js 中的一个全局对象,它提供了当前 Node.js 进程的相关信息,并允许你对其进行控制。

你可以把它想象成是 Node.js 程序的“大脑”或“控制中心”,无论你写的是多么简单的脚本,它都在一个 process 对象的“监视”下运行。
核心特点:
- 全局可用:你不需要
require('process')就能直接使用它,在任何地方都可以访问process。 - 事件驱动:
process对象本身就是一个EventEmitter,它会在特定事件发生时触发事件,比如程序即将退出、收到信号等。 - 信息枢纽:它包含了所有关于运行环境、程序输入输出的关键信息。
为什么 process 如此重要?
对于初学者来说,你可能不会在每行代码中都用到 process,但理解它是从“写脚本”到“写真正的应用程序”的关键一步,它的主要用途包括:
- 获取环境信息:比如你是在开发环境还是生产环境运行代码。
- 处理命令行参数:让你的脚本可以接收外部输入,变得更灵活。
- 控制程序的生命周期:优雅地处理程序退出、错误和中断。
- 读写标准输入/输出:与终端进行交互。
- 管理程序退出码:向操作系统或调用者(如 shell 脚本)表明程序是成功还是失败地结束。
核心属性和方法详解
我们来看一些 process 对象最常用、最重要的成员。

process.argv - 命令行参数
当你从命令行运行一个 Node.js 脚本时,你提供的所有参数都会被存储在 process.argv 数组中。
argv[0]: 总是 Node.js 可执行文件的路径。argv[1]: 总是被执行的 JavaScript 文件的路径。argv[2]及以后: 你自己传入的参数。
示例:
创建一个文件 args.js:
// args.js
console.log('process.argv:', process.argv);
// 遍历所有用户传入的参数
console.log('\n--- 用户传入的参数 ---');
for (let i = 2; i < process.argv.length; i++) {
console.log(`参数 ${i - 1}: ${process.argv[i]}`);
}
在终端中运行:

node args.js hello world 123
输出结果:
process.argv: [
'/path/to/your/node', // 你的 node 路径
'/path/to/your/args.js', // 你的文件路径
'hello',
'world',
'123'
]
--- 用户传入的参数 ---
参数 1: hello
参数 2: world
参数 3: 123
process.env - 环境变量
process.env 是一个对象,包含了所有在启动 Node.js 进程时设置的环境变量,这是管理不同环境(开发、测试、生产)配置的最佳实践。
示例:
在终端中设置一个环境变量,然后运行脚本。
# 在 Linux 或 macOS 中 MY_NAME="Alice" node env.js # 在 Windows PowerShell 中 $env:MY_NAME="Alice" ; node env.js # 在 Windows CMD 中 set MY_NAME=Alice && node env.js
创建一个文件 env.js:
// env.js
console.log('process.env.NODE_ENV:', process.env.NODE_ENV); // 常见的环境变量
console.log('process.env.MY_NAME:', process.env.MY_NAME); // 我们自定义的变量
// 如果没有设置,可以提供一个默认值
const dbHost = process.env.DB_HOST || 'localhost';
console.log('数据库连接地址:', dbHost);
输出结果:
process.env.NODE_ENV: undefined
process.env.MY_NAME: Alice
数据库连接地址: localhost
process.cwd() 和 __dirname - 工作目录与文件目录
process.cwd(): 返回 Node.js 进程的当前工作目录,这个目录是你在终端中执行node命令时所在的目录。__dirname: 一个全局变量(注意是两个下划线),返回当前 被执行的脚本所在的目录。
示例:
假设你的文件结构如下:
/my-project
├── scripts
│ └── path.js
└── package.json
进入 /my-project 目录并运行 node scripts/path.js。
创建 scripts/path.js:
// scripts/path.js
console.log('当前进程的工作目录 (process.cwd()):', process.cwd());
console.log('当前脚本所在的目录 (__dirname):', __dirname);
输出结果:
当前进程的工作目录 (process.cwd()): /my-project
当前脚本所在的目录 (__dirname): /my-project/scripts
process.exit([code]) - 退出进程
这个方法会立即终止 Node.js 进程。
code是一个可选的退出码,如果省略,默认是0,表示成功退出,非零值(如1)通常表示发生了错误。
示例:
创建 exit.js:
// exit.js
console.log('程序开始...');
// 模拟一个错误
const hasError = true;
if (hasError) {
console.log('发生严重错误,程序将退出。');
process.exit(1); // 以错误码 1 退出
}
console.log('程序正常结束。'); // 这行代码不会执行
在终端中运行并检查退出码:
node exit.js echo $? # 在 Linux/macOS 中查看上一个命令的退出码 # 或者 echo %ERRORLEVEL% # 在 Windows CMD 中查看
你会看到 程序开始... 和 发生严重错误... 被打印,echo $? 会输出 1。
process.on('exit', ...) 和 process.on('uncaughtException', ...) - 事件监听
process 对象是事件发射器,可以监听一些关键事件。
-
'exit'事件:在 Node.js 即将退出事件循环(event loop)之前触发。注意:在这个事件监听器中,只能执行同步操作,不能执行异步操作(如setTimeout),因为进程即将退出。 -
'uncaughtException'事件:当一个未捕获的 JavaScript 异常冒泡到事件循环顶层时触发,这相当于一个“最后的救命稻草”,可以防止进程直接崩溃。最佳实践:在监听此事件后,你应该记录错误并调用process.exit(1)来退出进程,而不是让程序继续在一个未知状态下运行。
示例:
创建 events.js:
// events.js
// 1. 监听 'exit' 事件
process.on('exit', (code) => {
// 这是一个同步操作
console.log(`进程即将退出,退出码是: ${code}`);
});
// 2. 监听 'uncaughtException' 事件
process.on('uncaughtException', (err) => {
// 同样,这里也应该是同步操作
console.error('捕获到一个未处理的异常!');
console.error(err.stack);
// 最好还是退出进程
process.exit(1);
});
// 3. 正常的 'SIGINT' 信号监听 (按下 Ctrl+C)
process.on('SIGINT', () => {
console.log('\n收到 SIGINT 信号 (Ctrl+C),正在优雅地关闭...');
// 在这里执行清理操作,然后退出
process.exit();
});
console.log('程序正在运行...');
// 故意制造一个未捕获的异常
setTimeout(() => {
throw new Error('这是一个故意的未捕获异常!');
}, 1000);
console.log('这段代码会在异常发生前打印。');
在终端中运行:
node events.js
你会看到:
程序正在运行...这段代码会在异常发生前打印。- 大约1秒后,会打印
捕获到一个未处理的异常!和错误堆栈。 - 然后进程退出,并打印
进程即将退出,退出码是: 1。
实战应用:创建一个简单的命令行工具
让我们用学到的知识创建一个简单的 CLI 工具,它可以根据参数执行不同的操作。
目标:
node cli.js --name YourName-> 输出Hello, YourName!node cli.js --task list-> 输出正在执行任务: list- 如果参数不正确,输出帮助信息。
创建 cli.js:
// cli.js
// 1. 获取用户传入的所有参数
const args = process.argv.slice(2); // 去掉前两个固定参数
// 2. 如果没有参数,打印帮助信息并退出
if (args.length === 0) {
console.log('用法:');
console.log(' node cli.js --name <你的名字>');
console.log(' node cli.js --task <任务名>');
process.exit(0);
}
// 3. 解析参数
// 我们使用一个简单的循环来查找 --name 和 --task
let name = '';
let task = '';
for (let i = 0; i < args.length; i++) {
if (args[i] === '--name' && i + 1 < args.length) {
name = args[i + 1];
i++; // 跳过下一个参数,因为它已经被当作值读取了
} else if (args[i] === '--task' && i + 1 < args.length) {
task = args[i + 1];
i++; // 同上
}
}
// 4. 根据解析到的参数执行逻辑
if (name) {
console.log(`Hello, ${name}!`);
} else if (task) {
console.log(`正在执行任务: ${task}`);
} else {
console.log('错误: 参数无效,请使用 --name 或 --task。');
process.exit(1);
}
测试:
# 测试 --name node cli.js --name Alice # 输出: Hello, Alice! # 测试 --task node cli.js --task build # 输出: 正在执行任务: build # 测试无参数 node cli.js # 输出用法说明 # 测试无效参数 node cli.js --foo # 输出: 错误: 参数无效,请使用 --name 或 --task。
| 成员/方法 | 描述 | 示例 |
|---|---|---|
process.argv |
获取命令行参数数组。 | node script.js arg1 arg2 |
process.env |
获取环境变量对象。 | process.env.NODE_ENV |
process.cwd() |
获取当前进程的工作目录。 | process.cwd() |
__dirname |
获取当前脚本所在目录。 | __dirname |
process.exit([code]) |
以指定码退出进程。 | process.exit(1) |
process.on('event', ...) |
监听进程事件。 | process.on('exit', ...) |
process.stdin |
标准输入流。 | process.stdin.pipe(process.stdout) |
process.stdout |
标准输出流。 | console.log 的底层就是它 |
process.stderr |
标准错误流。 | console.error 的底层就是它 |
process 是 Node.js 中一个非常基础且强大的模块,掌握它是成为一名合格 Node.js 开发者的必经之路,从今天起,尝试在写脚本时有意识地使用 process,你会发现你的程序变得更健壮、更灵活了。
