Node.js 核心模块
更新: 8/8/2025 字数: 0 字 时长: 0 分钟
Node.js 提供了许多内置的核心模块,无需安装即可使用。这些模块提供了文件系统操作、网络通信、路径处理等基础功能。
文件系统模块 (fs)
fs
模块提供了与文件系统交互的 API。
同步 vs 异步操作
javascript
const fs = require('fs');
// 异步读取文件
fs.readFile('example.txt', 'utf8', (err, data) => {
if (err) {
console.error('读取文件失败:', err);
return;
}
console.log('文件内容:', data);
});
// 使用 Promise 版本
const fsPromises = require('fs').promises;
async function readFileAsync() {
try {
const data = await fsPromises.readFile('example.txt', 'utf8');
console.log('文件内容:', data);
} catch (err) {
console.error('读取文件失败:', err);
}
}
javascript
const fs = require('fs');
try {
// 同步读取文件(会阻塞线程)
const data = fs.readFileSync('example.txt', 'utf8');
console.log('文件内容:', data);
} catch (err) {
console.error('读取文件失败:', err);
}
常用文件操作
javascript
const fs = require('fs');
const path = require('path');
// 写入文件
fs.writeFile('output.txt', 'Hello, Node.js!', 'utf8', (err) => {
if (err) {
console.error('写入失败:', err);
return;
}
console.log('文件写入成功');
});
// 追加内容到文件
fs.appendFile('output.txt', '\n追加的内容', 'utf8', (err) => {
if (err) {
console.error('追加失败:', err);
return;
}
console.log('内容追加成功');
});
// 检查文件是否存在
fs.access('example.txt', fs.constants.F_OK, (err) => {
if (err) {
console.log('文件不存在');
} else {
console.log('文件存在');
}
});
// 获取文件信息
fs.stat('example.txt', (err, stats) => {
if (err) {
console.error('获取文件信息失败:', err);
return;
}
console.log('文件大小:', stats.size, '字节');
console.log('是否为文件:', stats.isFile());
console.log('是否为目录:', stats.isDirectory());
console.log('创建时间:', stats.birthtime);
console.log('修改时间:', stats.mtime);
});
// 删除文件
fs.unlink('temp.txt', (err) => {
if (err) {
console.error('删除文件失败:', err);
return;
}
console.log('文件删除成功');
});
目录操作
javascript
const fs = require('fs');
// 创建目录
fs.mkdir('new-directory', { recursive: true }, (err) => {
if (err) {
console.error('创建目录失败:', err);
return;
}
console.log('目录创建成功');
});
// 读取目录内容
fs.readdir('.', (err, files) => {
if (err) {
console.error('读取目录失败:', err);
return;
}
console.log('目录内容:', files);
});
// 删除目录
fs.rmdir('old-directory', { recursive: true }, (err) => {
if (err) {
console.error('删除目录失败:', err);
return;
}
console.log('目录删除成功');
});
文件流操作
javascript
const fs = require('fs');
// 创建可读流
const readStream = fs.createReadStream('large-file.txt', {
encoding: 'utf8',
highWaterMark: 1024 // 缓冲区大小
});
readStream.on('data', (chunk) => {
console.log('读取到数据块:', chunk.length, '字符');
});
readStream.on('end', () => {
console.log('文件读取完成');
});
readStream.on('error', (err) => {
console.error('读取错误:', err);
});
// 创建可写流
const writeStream = fs.createWriteStream('output.txt', {
encoding: 'utf8'
});
writeStream.write('第一行内容\n');
writeStream.write('第二行内容\n');
writeStream.end('最后一行内容\n');
writeStream.on('finish', () => {
console.log('写入完成');
});
// 管道操作
const readStream2 = fs.createReadStream('input.txt');
const writeStream2 = fs.createWriteStream('copy.txt');
readStream2.pipe(writeStream2);
readStream2.on('end', () => {
console.log('文件复制完成');
});
路径模块 (path)
path
模块提供了处理文件和目录路径的工具。
javascript
const path = require('path');
// 路径拼接
const fullPath = path.join('/users', 'john', 'documents', 'file.txt');
console.log('完整路径:', fullPath);
// 输出: /users/john/documents/file.txt (Unix) 或 \users\john\documents\file.txt (Windows)
// 解析路径
const filePath = '/users/john/documents/file.txt';
console.log('目录名:', path.dirname(filePath)); // /users/john/documents
console.log('文件名:', path.basename(filePath)); // file.txt
console.log('扩展名:', path.extname(filePath)); // .txt
console.log('文件名(无扩展名):', path.basename(filePath, '.txt')); // file
// 路径解析对象
const parsed = path.parse(filePath);
console.log('解析结果:', parsed);
/*
{
root: '/',
dir: '/users/john/documents',
base: 'file.txt',
ext: '.txt',
name: 'file'
}
*/
// 格式化路径
const formatted = path.format({
dir: '/users/john/documents',
name: 'file',
ext: '.txt'
});
console.log('格式化路径:', formatted); // /users/john/documents/file.txt
// 绝对路径和相对路径
console.log('是否为绝对路径:', path.isAbsolute('/users/john')); // true
console.log('是否为绝对路径:', path.isAbsolute('documents/file.txt')); // false
// 解析相对路径为绝对路径
const absolutePath = path.resolve('documents', 'file.txt');
console.log('绝对路径:', absolutePath);
// 计算相对路径
const relativePath = path.relative('/users/john', '/users/john/documents/file.txt');
console.log('相对路径:', relativePath); // documents/file.txt
// 规范化路径
const normalizedPath = path.normalize('/users/john/../jane/./documents//file.txt');
console.log('规范化路径:', normalizedPath); // /users/jane/documents/file.txt
// 平台相关
console.log('路径分隔符:', path.sep); // '/' (Unix) 或 '\\' (Windows)
console.log('路径定界符:', path.delimiter); // ':' (Unix) 或 ';' (Windows)
HTTP 模块
http
模块用于创建 HTTP 服务器和客户端。
创建 HTTP 服务器
javascript
const http = require('http');
const url = require('url');
const querystring = require('querystring');
// 创建基本服务器
const server = http.createServer((req, res) => {
// 设置响应头
res.setHeader('Content-Type', 'text/html; charset=utf-8');
res.setHeader('Access-Control-Allow-Origin', '*');
// 解析 URL
const parsedUrl = url.parse(req.url, true);
const pathname = parsedUrl.pathname;
const query = parsedUrl.query;
console.log(`${req.method} ${req.url}`);
// 路由处理
if (pathname === '/') {
res.statusCode = 200;
res.end('<h1>欢迎访问 Node.js 服务器</h1>');
} else if (pathname === '/api/users') {
res.statusCode = 200;
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify({
users: [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
]
}));
} else if (pathname === '/api/echo' && req.method === 'POST') {
// 处理 POST 请求
let body = '';
req.on('data', (chunk) => {
body += chunk.toString();
});
req.on('end', () => {
res.statusCode = 200;
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify({
message: 'Echo',
data: body,
headers: req.headers
}));
});
} else {
res.statusCode = 404;
res.end('<h1>404 - 页面未找到</h1>');
}
});
// 监听端口
const PORT = process.env.PORT || 3000;
server.listen(PORT, () => {
console.log(`服务器运行在 http://localhost:${PORT}`);
});
// 错误处理
server.on('error', (err) => {
console.error('服务器错误:', err);
});
HTTP 客户端请求
javascript
const http = require('http');
const https = require('https');
// GET 请求
function makeGetRequest(url) {
return new Promise((resolve, reject) => {
const client = url.startsWith('https') ? https : http;
client.get(url, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
resolve({
statusCode: res.statusCode,
headers: res.headers,
data: data
});
});
}).on('error', (err) => {
reject(err);
});
});
}
// POST 请求
function makePostRequest(hostname, port, path, data) {
return new Promise((resolve, reject) => {
const postData = JSON.stringify(data);
const options = {
hostname: hostname,
port: port,
path: path,
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(postData)
}
};
const req = http.request(options, (res) => {
let responseData = '';
res.on('data', (chunk) => {
responseData += chunk;
});
res.on('end', () => {
resolve({
statusCode: res.statusCode,
headers: res.headers,
data: responseData
});
});
});
req.on('error', (err) => {
reject(err);
});
req.write(postData);
req.end();
});
}
// 使用示例
async function example() {
try {
// GET 请求
const getResponse = await makeGetRequest('http://localhost:3000/api/users');
console.log('GET 响应:', getResponse);
// POST 请求
const postResponse = await makePostRequest('localhost', 3000, '/api/echo', {
message: 'Hello from client'
});
console.log('POST 响应:', postResponse);
} catch (err) {
console.error('请求失败:', err);
}
}
事件模块 (events)
events
模块提供了事件发射器的实现。
javascript
const EventEmitter = require('events');
// 创建事件发射器
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
// 监听事件
myEmitter.on('event', (data) => {
console.log('事件触发:', data);
});
// 一次性监听
myEmitter.once('onceEvent', (data) => {
console.log('一次性事件:', data);
});
// 触发事件
myEmitter.emit('event', { message: 'Hello Events!' });
myEmitter.emit('onceEvent', { message: 'This will only fire once' });
myEmitter.emit('onceEvent', { message: 'This will not fire' });
// 错误处理
myEmitter.on('error', (err) => {
console.error('事件错误:', err);
});
// 移除监听器
function listener(data) {
console.log('临时监听器:', data);
}
myEmitter.on('temp', listener);
myEmitter.emit('temp', 'First call'); // 会触发
myEmitter.removeListener('temp', listener);
myEmitter.emit('temp', 'Second call'); // 不会触发
// 获取监听器信息
console.log('event 监听器数量:', myEmitter.listenerCount('event'));
console.log('所有事件名:', myEmitter.eventNames());
实际应用示例
javascript
const EventEmitter = require('events');
const fs = require('fs');
// 文件处理器类
class FileProcessor extends EventEmitter {
processFile(filePath) {
this.emit('start', { file: filePath });
fs.readFile(filePath, 'utf8', (err, data) => {
if (err) {
this.emit('error', err);
return;
}
this.emit('data', { file: filePath, content: data });
// 模拟处理时间
setTimeout(() => {
this.emit('complete', { file: filePath, size: data.length });
}, 1000);
});
}
}
// 使用文件处理器
const processor = new FileProcessor();
processor.on('start', (info) => {
console.log(`开始处理文件: ${info.file}`);
});
processor.on('data', (info) => {
console.log(`读取文件 ${info.file}, 内容长度: ${info.content.length}`);
});
processor.on('complete', (info) => {
console.log(`文件 ${info.file} 处理完成, 大小: ${info.size} 字符`);
});
processor.on('error', (err) => {
console.error('处理文件时出错:', err.message);
});
// 处理文件
processor.processFile('example.txt');
URL 模块
url
模块提供了 URL 解析和格式化功能。
javascript
const url = require('url');
// 解析 URL
const myUrl = 'https://www.example.com:8080/path/to/resource?name=john&age=30#section1';
// 使用 url.parse() (已废弃,但仍可用)
const parsed = url.parse(myUrl, true);
console.log('解析结果:', parsed);
/*
{
protocol: 'https:',
slashes: true,
auth: null,
host: 'www.example.com:8080',
port: '8080',
hostname: 'www.example.com',
hash: '#section1',
search: '?name=john&age=30',
query: { name: 'john', age: '30' },
pathname: '/path/to/resource',
path: '/path/to/resource?name=john&age=30',
href: 'https://www.example.com:8080/path/to/resource?name=john&age=30#section1'
}
*/
// 使用 URL 构造函数 (推荐)
const myURL = new URL(myUrl);
console.log('协议:', myURL.protocol); // https:
console.log('主机:', myURL.hostname); // www.example.com
console.log('端口:', myURL.port); // 8080
console.log('路径:', myURL.pathname); // /path/to/resource
console.log('查询参数:', myURL.search); // ?name=john&age=30
console.log('哈希:', myURL.hash); // #section1
// 操作查询参数
console.log('name 参数:', myURL.searchParams.get('name')); // john
myURL.searchParams.set('city', 'beijing');
myURL.searchParams.delete('age');
console.log('修改后的 URL:', myURL.toString());
// 格式化 URL
const urlObject = {
protocol: 'https:',
hostname: 'api.example.com',
port: 443,
pathname: '/v1/users',
search: '?limit=10&offset=0'
};
const formattedUrl = url.format(urlObject);
console.log('格式化的 URL:', formattedUrl);
// 解析相对 URL
const baseUrl = 'https://www.example.com/api/';
const relativeUrl = '../users/profile';
const absoluteUrl = new URL(relativeUrl, baseUrl);
console.log('绝对 URL:', absoluteUrl.toString()); // https://www.example.com/users/profile
查询字符串模块 (querystring)
javascript
const querystring = require('querystring');
// 解析查询字符串
const query = 'name=john&age=30&city=beijing&hobbies=reading&hobbies=coding';
const parsed = querystring.parse(query);
console.log('解析结果:', parsed);
// { name: 'john', age: '30', city: 'beijing', hobbies: ['reading', 'coding'] }
// 格式化对象为查询字符串
const obj = {
name: 'alice',
age: 25,
city: 'shanghai',
hobbies: ['music', 'travel']
};
const stringified = querystring.stringify(obj);
console.log('格式化结果:', stringified);
// name=alice&age=25&city=shanghai&hobbies=music&hobbies=travel
// 自定义分隔符
const customQuery = 'name:john;age:30;city:beijing';
const customParsed = querystring.parse(customQuery, ';', ':');
console.log('自定义解析:', customParsed);
// { name: 'john', age: '30', city: 'beijing' }
// URL 编码和解码
const encoded = querystring.escape('hello world & 你好');
console.log('编码结果:', encoded); // hello%20world%20%26%20%E4%BD%A0%E5%A5%BD
const decoded = querystring.unescape(encoded);
console.log('解码结果:', decoded); // hello world & 你好
操作系统模块 (os)
javascript
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.release());
console.log('主机名:', os.hostname());
// 内存信息
console.log('总内存:', (os.totalmem() / 1024 / 1024 / 1024).toFixed(2), 'GB');
console.log('空闲内存:', (os.freemem() / 1024 / 1024 / 1024).toFixed(2), 'GB');
// CPU 信息
const cpus = os.cpus();
console.log('CPU 核心数:', cpus.length);
console.log('CPU 型号:', cpus[0].model);
console.log('CPU 速度:', cpus[0].speed, 'MHz');
// 网络接口
const networkInterfaces = os.networkInterfaces();
console.log('网络接口:', Object.keys(networkInterfaces));
// 用户信息
console.log('当前用户:', os.userInfo());
// 系统负载 (仅 Unix 系统)
if (os.platform() !== 'win32') {
console.log('系统负载:', os.loadavg());
}
// 系统运行时间
const uptime = os.uptime();
console.log('系统运行时间:', Math.floor(uptime / 3600), '小时');
// 临时目录
console.log('临时目录:', os.tmpdir());
// 行结束符
console.log('行结束符:', JSON.stringify(os.EOL)); // "\n" (Unix) 或 "\r\n" (Windows)
加密模块 (crypto)
javascript
const crypto = require('crypto');
// 生成随机数据
const randomBytes = crypto.randomBytes(16);
console.log('随机字节:', randomBytes.toString('hex'));
// 哈希函数
const hash = crypto.createHash('sha256');
hash.update('Hello, World!');
const hashResult = hash.digest('hex');
console.log('SHA256 哈希:', hashResult);
// 简化的哈希计算
const quickHash = crypto.createHash('md5').update('Hello, World!').digest('hex');
console.log('MD5 哈希:', quickHash);
// HMAC (Hash-based Message Authentication Code)
const hmac = crypto.createHmac('sha256', 'secret-key');
hmac.update('Hello, World!');
const hmacResult = hmac.digest('hex');
console.log('HMAC:', hmacResult);
// 对称加密 (AES)
function encrypt(text, password) {
const algorithm = 'aes-256-cbc';
const key = crypto.scryptSync(password, 'salt', 32);
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipher(algorithm, key);
let encrypted = cipher.update(text, 'utf8', 'hex');
encrypted += cipher.final('hex');
return {
iv: iv.toString('hex'),
encryptedData: encrypted
};
}
function decrypt(encryptedData, password) {
const algorithm = 'aes-256-cbc';
const key = crypto.scryptSync(password, 'salt', 32);
const decipher = crypto.createDecipher(algorithm, key);
let decrypted = decipher.update(encryptedData, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}
// 使用加密
const originalText = '这是需要加密的敏感信息';
const password = 'my-secret-password';
const encrypted = encrypt(originalText, password);
console.log('加密结果:', encrypted);
const decrypted = decrypt(encrypted.encryptedData, password);
console.log('解密结果:', decrypted);
// 生成密钥对 (RSA)
const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
modulusLength: 2048,
publicKeyEncoding: {
type: 'spki',
format: 'pem'
},
privateKeyEncoding: {
type: 'pkcs8',
format: 'pem'
}
});
console.log('公钥:', publicKey);
console.log('私钥:', privateKey);
实用工具模块 (util)
javascript
const util = require('util');
const fs = require('fs');
// promisify - 将回调函数转换为 Promise
const readFileAsync = util.promisify(fs.readFile);
async function readFile() {
try {
const data = await readFileAsync('example.txt', 'utf8');
console.log('文件内容:', data);
} catch (err) {
console.error('读取失败:', err);
}
}
// inspect - 格式化对象输出
const obj = {
name: 'John',
age: 30,
address: {
city: 'Beijing',
country: 'China'
},
hobbies: ['reading', 'coding']
};
console.log('格式化输出:');
console.log(util.inspect(obj, {
colors: true,
depth: null,
compact: false
}));
// format - 字符串格式化
const formatted = util.format('用户 %s 今年 %d 岁', 'Alice', 25);
console.log(formatted); // 用户 Alice 今年 25 岁
// 类型检查
console.log('是否为数组:', util.isArray([1, 2, 3])); // true
console.log('是否为日期:', util.isDate(new Date())); // true
console.log('是否为错误:', util.isError(new Error())); // true
// 继承
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
console.log(`${this.name} makes a sound`);
};
function Dog(name, breed) {
Animal.call(this, name);
this.breed = breed;
}
// 设置原型链继承
util.inherits(Dog, Animal);
Dog.prototype.bark = function() {
console.log(`${this.name} barks!`);
};
const dog = new Dog('Buddy', 'Golden Retriever');
dog.speak(); // Buddy makes a sound
dog.bark(); // Buddy barks!
最佳实践
- 优先使用异步 API:避免阻塞事件循环
- 错误处理:始终处理异步操作的错误
- 使用 Promise 或 async/await:提高代码可读性
- 合理使用流:处理大文件时使用流而不是一次性读取
- 路径处理:使用
path
模块处理文件路径,确保跨平台兼容性 - 安全性:使用
crypto
模块进行加密和哈希操作