Node.js 核心模块
Node.js 提供了丰富的核心模块,无需安装即可使用。本章将介绍常用的核心模块。
核心模块概览
| 模块 | 功能 |
|---|---|
path | 路径处理 |
fs | 文件系统操作 |
os | 操作系统信息 |
util | 实用工具函数 |
crypto | 加密和解密 |
url | URL 解析 |
querystring | 查询字符串解析 |
events | 事件处理 |
stream | 流处理 |
http | HTTP 服务 |
https | HTTPS 服务 |
net | 网络 TCP/IPC |
child_process | 子进程 |
cluster | 多进程集群 |
path 模块
path 模块用于处理文件和目录路径。
const path = require('path');
// 路径拼接
const fullPath = path.join('/home', 'user', 'docs', 'file.txt');
console.log(fullPath);
// 输出:/home/user/docs/file.txt(Linux/macOS)
// 输出:home\user\docs\file.txt(Windows)
// 解析路径
const parsed = path.parse('/home/user/docs/file.txt');
console.log(parsed);
// {
// root: '/',
// dir: '/home/user/docs',
// base: 'file.txt',
// ext: '.txt',
// name: 'file'
// }
// 获取路径各部分
path.basename('/home/user/file.txt'); // 'file.txt'
path.basename('/home/user/file.txt', '.txt'); // 'file'
path.dirname('/home/user/file.txt'); // '/home/user'
path.extname('/home/user/file.txt'); // '.txt'
// 获取绝对路径
path.resolve('docs', 'file.txt'); // '/current/dir/docs/file.txt'
path.resolve('/home', 'user', 'docs'); // '/home/user/docs'
// 规范化路径
path.normalize('/home/user/../docs/./file.txt'); // '/home/docs/file.txt'
// 判断是否为绝对路径
path.isAbsolute('/home/user'); // true
path.isAbsolute('./user'); // false
// 相对路径
path.relative('/home/user', '/home/docs'); // '../docs'
// 路径分隔符
path.sep // '/' (Linux/macOS) 或 '\' (Windows)
path.delimiter // ':' (Linux/macOS) 或 ';' (Windows)
解释:
path.join()拼接路径,自动处理分隔符path.resolve()解析为绝对路径path.parse()返回路径对象,包含各部分信息- 使用
path模块可以编写跨平台的路径处理代码
os 模块
os 模块提供操作系统相关信息。
const os = require('os');
// 系统信息
console.log('操作系统:', os.type()); // Linux, Darwin, Windows_NT
console.log('平台:', os.platform()); // linux, darwin, win32
console.log('架构:', os.arch()); // x64, arm64
console.log('主机名:', os.hostname()); // 计算机名
console.log('版本:', os.release()); // 系统版本
// CPU 信息
console.log('CPU 数量:', os.cpus().length);
console.log('CPU 信息:', os.cpus()[0].model);
// 内存信息
console.log('总内存:', os.totalmem() / 1024 / 1024 / 1024, 'GB');
console.log('可用内存:', os.freemem() / 1024 / 1024 / 1024, 'GB');
console.log('内存使用率:',
((os.totalmem() - os.freemem()) / os.totalmem() * 100).toFixed(2), '%');
// 网络接口
const interfaces = os.networkInterfaces();
console.log('网络接口:', Object.keys(interfaces));
// 用户信息
console.log('用户信息:', os.userInfo());
// 系统运行时间(秒)
console.log('系统运行时间:', os.uptime() / 3600, '小时');
// 临时目录
console.log('临时目录:', os.tmpdir());
// 主目录
console.log('主目录:', os.homedir());
// 换行符
console.log('换行符:', JSON.stringify(os.EOL)); // '\n' 或 '\r\n'
实际应用:
// 监控系统资源
function getSystemStats() {
const totalMem = os.totalmem();
const freeMem = os.freemem();
const usedMem = totalMem - freeMem;
return {
cpu: {
count: os.cpus().length,
model: os.cpus()[0].model,
speed: os.cpus()[0].speed
},
memory: {
total: (totalMem / 1024 / 1024 / 1024).toFixed(2) + ' GB',
used: (usedMem / 1024 / 1024 / 1024).toFixed(2) + ' GB',
free: (freeMem / 1024 / 1024 / 1024).toFixed(2) + ' GB',
usage: (usedMem / totalMem * 100).toFixed(2) + '%'
},
uptime: (os.uptime() / 3600).toFixed(2) + ' hours',
platform: os.platform(),
hostname: os.hostname()
};
}
console.log(getSystemStats());
util 模块
util 模块提供实用工具函数。
promisify
将回调风格的函数转换为 Promise:
const util = require('util');
const fs = require('fs');
// 传统回调方式
fs.readFile('file.txt', 'utf8', (err, data) => {
if (err) throw err;
console.log(data);
});
// 使用 promisify 转换
const readFile = util.promisify(fs.readFile);
async function readConfig() {
try {
const data = await readFile('file.txt', 'utf8');
console.log(data);
} catch (err) {
console.error('读取失败:', err);
}
}
readConfig();
callbackify
将 Promise 转换为回调风格:
const util = require('util');
async function asyncFunction() {
return 'Hello';
}
const callbackFunction = util.callbackify(asyncFunction);
callbackFunction((err, result) => {
if (err) throw err;
console.log(result); // 'Hello'
});
format 格式化字符串
const util = require('util');
// %s - 字符串
// %d - 数字
// %j - JSON
// %% - 百分号
console.log(util.format('Hello, %s!', 'World')); // Hello, World!
console.log(util.format('%s has %d apples', 'Tom', 3)); // Tom has 3 apples
console.log(util.format('JSON: %j', { name: 'Tom' })); // JSON: {"name":"Tom"}
console.log(util.format('%% %s', 'test')); // % test
inherits(已废弃)
继承另一个类的原型方法(推荐使用 ES6 class 和 extends):
// 不推荐使用 util.inherits
// 推荐使用 ES6 类继承
class EventEmitter {
emit(event) { /* ... */ }
}
class MyEmitter extends EventEmitter {
constructor() {
super();
}
}
inspect
将对象转换为字符串用于调试:
const util = require('util');
const obj = {
name: 'Tom',
nested: {
deep: {
value: 42
}
}
};
console.log(util.inspect(obj, {
depth: null, // 无限深度
colors: true, // 彩色输出
compact: false // 格式化输出
}));
url 模块
url 模块用于 URL 解析和处理。
新版 API(推荐)
const url = require('url');
const myUrl = new URL('https://user:[email protected]:8080/path/name?q=hello#anchor');
console.log('协议:', myUrl.protocol); // https:
console.log('主机名:', myUrl.hostname); // host.com
console.log('端口:', myUrl.port); // 8080
console.log('路径:', myUrl.pathname); // /path/name
console.log('查询字符串:', myUrl.search); // ?q=hello
console.log('哈希:', myUrl.hash); // #anchor
console.log('用户名:', myUrl.username); // user
console.log('密码:', myUrl.password); // pass
// 修改 URL
myUrl.pathname = '/new/path';
myUrl.searchParams.append('page', '1');
console.log(myUrl.href);
// https://user:[email protected]:8080/new/path?q=hello&page=1#anchor
URLSearchParams
const params = new URLSearchParams('q=hello&page=1');
// 获取参数
console.log(params.get('q')); // 'hello'
console.log(params.has('page')); // true
// 设置参数
params.set('size', '10');
params.append('tag', 'node');
params.delete('page');
// 遍历参数
for (const [key, value] of params) {
console.log(`${key}: ${value}`);
}
// 转换为字符串
console.log(params.toString()); // q=hello&size=10&tag=node
// 转换为对象
console.log(Object.fromEntries(params));
// { q: 'hello', size: '10', tag: 'node' }
querystring 模块
querystring 模块用于解析和格式化查询字符串(已废弃,推荐使用 URLSearchParams)。
const querystring = require('querystring');
// 解析查询字符串
const params = querystring.parse('name=Tom&age=25&hobbies=reading&hobbies=coding');
console.log(params);
// { name: 'Tom', age: '25', hobbies: ['reading', 'coding'] }
// 序列化为查询字符串
const str = querystring.stringify({ name: 'Tom', age: 25 });
console.log(str); // name=Tom&age=25
// 编码解码
querystring.escape('你好 世界'); // '%E4%BD%A0%E5%A5%BD%20%E4%B8%96%E7%95%8C'
querystring.unescape('%E4%BD%A0%E5%A5%BD'); // '你好'
推荐使用 URLSearchParams:
// 替代方案
const params = new URLSearchParams('name=Tom&age=25');
console.log(params.get('name')); // Tom
crypto 模块
crypto 模块提供加密功能。
哈希
const crypto = require('crypto');
// 创建哈希
const hash = crypto.createHash('sha256');
hash.update('Hello, World!');
console.log(hash.digest('hex'));
// dffd6021bb2bd...
// 链式调用
const sha256 = crypto.createHash('sha256').update('Hello').digest('hex');
// 支持 MD5、SHA-1、SHA-256、SHA-512 等
const md5 = crypto.createHash('md5').update('password').digest('hex');
const sha1 = crypto.createHash('sha1').update('password').digest('hex');
HMAC
const crypto = require('crypto');
// HMAC(带密钥的哈希)
const secret = 'my-secret-key';
const hmac = crypto.createHmac('sha256', secret);
hmac.update('Hello, World!');
console.log(hmac.digest('hex'));
对称加密
const crypto = require('crypto');
// 加密算法
const algorithm = 'aes-256-cbc';
const key = crypto.randomBytes(32); // 32 字节密钥
const iv = crypto.randomBytes(16); // 16 字节初始化向量
// 加密
function encrypt(text) {
const cipher = crypto.createCipheriv(algorithm, key, iv);
let encrypted = cipher.update(text, 'utf8', 'hex');
encrypted += cipher.final('hex');
return encrypted;
}
// 解密
function decrypt(encrypted) {
const decipher = crypto.createDecipheriv(algorithm, key, iv);
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}
const encrypted = encrypt('Hello, World!');
const decrypted = decrypt(encrypted);
console.log('加密:', encrypted);
console.log('解密:', decrypted);
随机数
const crypto = require('crypto');
// 生成随机字节
crypto.randomBytes(16, (err, buffer) => {
console.log(buffer.toString('hex'));
});
// 同步版本
const randomBytes = crypto.randomBytes(16).toString('hex');
// 生成随机整数
const randomInt = crypto.randomInt(0, 100); // 0-99 之间的随机整数
// 生成 UUID
const uuid = crypto.randomUUID();
console.log(uuid); // '550e8400-e29b-41d4-a716-446655440000'
最佳实践
1. 使用 path 模块处理路径
// ❌ 不推荐:手动拼接路径
const filePath = __dirname + '/data/' + filename;
// ✅ 推荐:使用 path.join
const filePath = path.join(__dirname, 'data', filename);
2. 使用 promisify 或 fs.promises
// ❌ 不推荐:回调地狱
fs.readFile('file1.txt', (err, data1) => {
fs.readFile('file2.txt', (err, data2) => {
// ...
});
});
// ✅ 推荐:使用 Promise
const readFile = util.promisify(fs.readFile);
const [data1, data2] = await Promise.all([
readFile('file1.txt'),
readFile('file2.txt')
]);
3. 安全地处理敏感数据
// ❌ 不推荐:明文存储密码
const password = '123456';
// ✅ 推荐:使用加密哈希
const hashedPassword = crypto
.createHash('sha256')
.update(password + salt)
.digest('hex');
小结
本章我们学习了:
- path 模块:路径拼接、解析、规范化
- os 模块:获取系统信息
- util 模块:promisify、format、inspect
- url 模块:URL 解析和处理
- querystring 模块:查询字符串处理
- crypto 模块:哈希、加密、随机数
练习
- 使用 path 模块获取文件扩展名和父目录
- 使用 os 模块编写一个系统监控脚本
- 使用 promisify 将 fs.readFile 转换为 Promise
- 使用 URLSearchParams 解析 URL 查询参数
- 使用 crypto 模块实现简单的密码加密