path:路径处理
import path from 'path';
// 拼接(跨平台)
path.join('a', 'b', 'c'); // 'a/b/c'(Linux)或 'a\\b\\c'(Windows)
path.join(__dirname, 'data', 'config.json');
// 解析(绝对路径)
path.resolve('a', 'b'); // /cwd/a/b
path.resolve('/foo', 'bar'); // /foo/bar
path.resolve('./relative'); // /cwd/relative
// 拆解
const p = '/home/wadely/project/index.js';
path.basename(p) // 'index.js'
path.basename(p, '.js') // 'index'
path.dirname(p) // '/home/wadely/project'
path.extname(p) // '.js'
// 解构所有
path.parse(p)
// { root: '/', dir: '/home/wadely/project', base: 'index.js', ext: '.js', name: 'index' }
// 反向(拼回字符串)
path.format({ dir: '/home', name: 'a', ext: '.txt' }) // '/home/a.txt'
// 相对路径
path.relative('/data/a', '/data/b/c'); // '../b/c'
path.posix vs path.win32
path.posix.join('a', 'b'); // 'a/b'(永远用 /)
path.win32.join('a', 'b'); // 'a\\b'(永远用 \)
os:系统信息
import os from 'os';
os.platform() // 'linux' / 'darwin' / 'win32'
os.arch() // 'x64' / 'arm64'
os.release() // 系统内核版本
os.hostname() // 主机名
os.cpus() // CPU 信息数组
os.cpus().length // 核数
os.totalmem() // 总内存(字节)
os.freemem() // 空闲内存
os.loadavg() // [1分,5分,15分] 负载(Linux/macOS)
os.uptime() // 系统开机秒数
os.userInfo() // { username, uid, gid, shell, homedir }
os.tmpdir() // 临时目录 /tmp 或 C:\Users\..\Temp
os.homedir() // 家目录
os.networkInterfaces() // 网卡列表
os.EOL // 换行符(\n 或 \r\n)
os.constants.signals // SIGTERM = 15 等
实战:
// 多核应用根据核数起子进程
const workers = Math.max(1, os.cpus().length - 1);
// 跨平台换行
const lines = data.split(os.EOL);
// 跨平台临时文件
import { join } from 'path';
const tmpFile = join(os.tmpdir(), 'myapp.tmp');
process:进程对象
process.argv // 启动参数数组
process.env // 环境变量对象
process.env.NODE_ENV // 常用
process.env.HOME // 跨平台用 os.homedir()
process.cwd() // 当前工作目录
process.chdir('/tmp') // 切目录
process.pid // 当前 PID
process.ppid // 父进程 PID
process.platform // 同 os.platform()
process.arch // 同 os.arch()
process.version // Node 版本
process.uptime() // 进程跑了多久(秒)
process.memoryUsage() // 内存:rss / heapTotal / heapUsed / external
process.cpuUsage() // CPU 时间
process.exit(0) // 退出(小心用,跳过清理)
process.exitCode = 1 // 设退出码但等自然退出
信号处理
process.on('SIGINT', () => { // Ctrl+C
console.log('Got SIGINT, cleaning up...');
process.exit(0);
});
process.on('SIGTERM', () => { // kill 信号
server.close(() => process.exit(0));
});
process.on('uncaughtException', (err) => {
console.error('Uncaught:', err);
process.exit(1);
});
process.on('unhandledRejection', (reason) => {
console.error('Unhandled rejection:', reason);
process.exit(1);
});
process.on('exit', (code) => {
// 同步清理(异步在这里不可靠)
console.log(`Exiting with code ${code}`);
});
标准输入输出
process.stdin // ReadStream
process.stdout // WriteStream
process.stderr // WriteStream
process.stdout.write('hello'); // 无换行(console.log 有)
process.stderr.write('error'); // 写到 stderr
实战:优雅退出
const server = http.createServer(...);
server.listen(8080);
let shuttingDown = false;
async function shutdown(signal) {
if (shuttingDown) return;
shuttingDown = true;
console.log(`${signal} received, shutting down...`);
server.close();
await db.close();
process.exit(0);
}
process.on('SIGTERM', () => shutdown('SIGTERM'));
process.on('SIGINT', () => shutdown('SIGINT'));
坑
process.exit(0)不会等待 Promise / pending I/O—— 用process.exitCode = 0自然退出- 环境变量永远是字符串(不是 boolean / number)——
process.env.DEBUG === 'true'才行 - Windows 没 SIGTERM 信号——跨平台脚本要小心
process.argv[0]是 node 路径,[1]是脚本路径,用户参数从[2]起
下一篇:Stream。