Node.js 基础知识
一、Node.js 概述
1.1 什么是 Node.js
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时环境,让 JavaScript 可以在服务器端运行。
核心特点:
- 事件驱动、非阻塞 I/O
- 单线程、异步编程
- 跨平台(Windows、macOS、Linux)
- 丰富的生态系统(npm)
1.2 适用场景
| 场景 | 说明 |
|---|---|
| Web 服务器 | API 服务、后端应用 |
| 实时应用 | WebSocket、聊天室 |
| 工具开发 | 构建工具、CLI 工具 |
| 微服务 | 轻量级服务节点 |
| 全栈开发 | 前后端统一语言 |
1.3 安装与版本管理
使用 NVM 管理版本:
# 安装 LTS 版本
nvm install --lts
# 切换版本
nvm use 18.17.0
# 查看版本
node -v
npm -v
二、核心模块
2.1 fs(文件系统)
读取文件:
const fs = require('fs');
// 同步读取
const data = fs.readFileSync('file.txt', 'utf8');
console.log(data);
// 异步读取
fs.readFile('file.txt', 'utf8', (err, data) => {
if (err) throw err;
console.log(data);
});
// Promise 方式(Node 14+)
const fsPromises = require('fs').promises;
async function readFile() {
const data = await fsPromises.readFile('file.txt', 'utf8');
console.log(data);
}
写入文件:
// 异步写入
fs.writeFile('output.txt', 'Hello Node.js', (err) => {
if (err) throw err;
console.log('文件已保存');
});
// 追加内容
fs.appendFile('output.txt', '\n追加内容', (err) => {
if (err) throw err;
});
目录操作:
// 创建目录
fs.mkdir('newDir', (err) => {
if (err) throw err;
});
// 读取目录
fs.readdir('.', (err, files) => {
if (err) throw err;
files.forEach(file => console.log(file));
});
// 删除文件
fs.unlink('file.txt', (err) => {
if (err) throw err;
});
2.2 path(路径处理)
const path = require('path');
// 路径拼接
path.join('/foo', 'bar', 'baz/asdf'); // '/foo/bar/baz/asdf'
// 获取文件名
path.basename('/foo/bar/baz.txt'); // 'baz.txt'
// 获取目录名
path.dirname('/foo/bar/baz.txt'); // '/foo/bar'
// 获取扩展名
path.extname('index.html'); // '.html'
// 解析路径
path.parse('/home/user/dir/file.txt');
// {
// root: '/',
// dir: '/home/user/dir',
// base: 'file.txt',
// ext: '.txt',
// name: 'file'
// }
// 绝对路径
path.resolve('foo', 'bar'); // '/current/dir/foo/bar'
2.3 http(HTTP 服务器)
创建服务器:
const http = require('http');
const server = http.createServer((req, res) => {
// 设置响应头
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
// 路由处理
if (req.url === '/') {
res.end('<h1>首页</h1>');
} else if (req.url === '/about') {
res.end('<h1>关于</h1>');
} else {
res.writeHead(404);
res.end('<h1>404 Not Found</h1>');
}
});
server.listen(3000, () => {
console.log('服务器运行在 http://localhost:3000');
});
处理 POST 请求:
const http = require('http');
const server = http.createServer((req, res) => {
if (req.method === 'POST') {
let body = '';
req.on('data', chunk => {
body += chunk.toString();
});
req.on('end', () => {
const data = JSON.parse(body);
console.log('接收到的数据:', data);
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ success: true }));
});
}
});
server.listen(3000);
2.4 url(URL 解析)
const url = require('url');
const myURL = new URL('https://example.com:8080/path?name=value#hash');
console.log(myURL.href); // 'https://example.com:8080/path?name=value#hash'
console.log(myURL.protocol); // 'https:'
console.log(myURL.host); // 'example.com:8080'
console.log(myURL.hostname); // 'example.com'
console.log(myURL.port); // '8080'
console.log(myURL.pathname); // '/path'
console.log(myURL.search); // '?name=value'
console.log(myURL.hash); // '#hash'
// 获取查询参数
console.log(myURL.searchParams.get('name')); // 'value'
2.5 querystring(查询字符串)
const querystring = require('querystring');
// 解析查询字符串
const params = querystring.parse('name=张三&age=25');
console.log(params); // { name: '张三', age: '25' }
// 序列化为查询字符串
const str = querystring.stringify({ name: '张三', age: 25 });
console.log(str); // 'name=%E5%BC%A0%E4%B8%89&age=25'
三、异步编程
3.1 回调函数
// 回调地狱示例
fs.readFile('file1.txt', (err, data1) => {
if (err) throw err;
fs.readFile('file2.txt', (err, data2) => {
if (err) throw err;
fs.readFile('file3.txt', (err, data3) => {
if (err) throw err;
console.log(data1 + data2 + data3);
});
});
});
3.2 Promise
const fsPromises = require('fs').promises;
// Promise 链式调用
fsPromises.readFile('file1.txt', 'utf8')
.then(data1 => {
return fsPromises.readFile('file2.txt', 'utf8');
})
.then(data2 => {
return fsPromises.readFile('file3.txt', 'utf8');
})
.then(data3 => {
console.log(data1 + data2 + data3);
})
.catch(err => {
console.error('错误:', err);
});
// Promise.all 并行执行
Promise.all([
fsPromises.readFile('file1.txt', 'utf8'),
fsPromises.readFile('file2.txt', 'utf8'),
fsPromises.readFile('file3.txt', 'utf8')
])
.then(([data1, data2, data3]) => {
console.log(data1 + data2 + data3);
})
.catch(err => {
console.error('错误:', err);
});
3.3 async/await
async function readFiles() {
try {
const data1 = await fsPromises.readFile('file1.txt', 'utf8');
const data2 = await fsPromises.readFile('file2.txt', 'utf8');
const data3 = await fsPromises.readFile('file3.txt', 'utf8');
console.log(data1 + data2 + data3);
} catch (err) {
console.error('错误:', err);
}
}
// 并行执行
async function readFilesParallel() {
try {
const [data1, data2, data3] = await Promise.all([
fsPromises.readFile('file1.txt', 'utf8'),
fsPromises.readFile('file2.txt', 'utf8'),
fsPromises.readFile('file3.txt', 'utf8')
]);
console.log(data1 + data2 + data3);
} catch (err) {
console.error('错误:', err);
}
}
3.4 事件(EventEmitter)
const EventEmitter = require('events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
// 监听事件
myEmitter.on('event', (data) => {
console.log('事件触发:', data);
});
// 触发事件
myEmitter.emit('event', { message: 'Hello' });
// 只监听一次
myEmitter.once('event', () => {
console.log('只触发一次');
});
// 移除监听器
myEmitter.removeListener('event', handler);
四、npm 包管理
4.1 常用命令
# 初始化项目
npm init
npm init -y # 快速初始化
# 安装包
npm install express # 安装到 dependencies
npm install -D nodemon # 安装到 devDependencies
npm install -g nodemon # 全局安装
# 卸载包
npm uninstall express
# 更新包
npm update express
# 查看包信息
npm list # 查看已安装的包
npm list -g # 查看全局包
npm info express # 查看包信息
# 运行脚本
npm run start
npm run dev
4.2 package.json
{
"name": "my-app",
"version": "1.0.0",
"description": "项目描述",
"main": "index.js",
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js",
"test": "jest"
},
"dependencies": {
"express": "^4.18.0"
},
"devDependencies": {
"nodemon": "^2.0.20"
},
"engines": {
"node": ">=14.0.0"
}
}
4.3 常用包
| 包名 | 用途 |
|---|---|
| express | Web 框架 |
| nodemon | 开发时自动重启 |
| dotenv | 环境变量管理 |
| cors | 跨域处理 |
| body-parser | 请求体解析 |
| mongoose | MongoDB 驱动 |
| mysql2 | MySQL 驱动 |
| axios | HTTP 客户端 |
| bcrypt | 密码加密 |
| jsonwebtoken | JWT 认证 |
五、Express 框架
5.1 基础使用
const express = require('express');
const app = express();
const PORT = 3000;
// 中间件:解析 JSON
app.use(express.json());
// 路由
app.get('/', (req, res) => {
res.send('Hello Express');
});
app.get('/api/users', (req, res) => {
res.json({ users: [] });
});
app.post('/api/users', (req, res) => {
const user = req.body;
// 处理逻辑
res.status(201).json({ success: true, user });
});
app.listen(PORT, () => {
console.log(`服务器运行在 http://localhost:${PORT}`);
});
5.2 路由
// 路由参数
app.get('/users/:id', (req, res) => {
const userId = req.params.id;
res.json({ userId });
});
// 查询参数
app.get('/search', (req, res) => {
const keyword = req.query.keyword;
res.json({ keyword });
});
// 路由模块化
// routes/users.js
const express = require('express');
const router = express.Router();
router.get('/', (req, res) => {
res.json({ users: [] });
});
router.get('/:id', (req, res) => {
res.json({ user: { id: req.params.id } });
});
module.exports = router;
// app.js
const usersRouter = require('./routes/users');
app.use('/api/users', usersRouter);
5.3 中间件
// 自定义中间件
const logger = (req, res, next) => {
console.log(`${req.method} ${req.url} - ${new Date()}`);
next();
};
app.use(logger);
// 错误处理中间件
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: '服务器错误' });
});
// 静态文件服务
app.use(express.static('public'));
// CORS 中间件
const cors = require('cors');
app.use(cors());
六、数据库连接
6.1 MongoDB(Mongoose)
const mongoose = require('mongoose');
// 连接数据库
mongoose.connect('mongodb://localhost:27017/myapp', {
useNewUrlParser: true,
useUnifiedTopology: true
});
// 定义模型
const UserSchema = new mongoose.Schema({
name: String,
email: { type: String, required: true, unique: true },
age: Number,
createdAt: { type: Date, default: Date.now }
});
const User = mongoose.model('User', UserSchema);
// CRUD 操作
async function userOperations() {
// 创建
const user = await User.create({
name: '张三',
email: 'zhangsan@example.com',
age: 25
});
// 查询
const users = await User.find();
const user = await User.findById(userId);
const user = await User.findOne({ email: 'zhangsan@example.com' });
// 更新
await User.findByIdAndUpdate(userId, { age: 26 });
// 删除
await User.findByIdAndDelete(userId);
}
6.2 MySQL(mysql2)
const mysql = require('mysql2/promise');
// 创建连接池
const pool = mysql.createPool({
host: 'localhost',
user: 'root',
password: 'password',
database: 'myapp',
waitForConnections: true,
connectionLimit: 10
});
// 查询
async function queryUsers() {
const [rows] = await pool.execute('SELECT * FROM users WHERE id = ?', [1]);
return rows;
}
// 插入
async function createUser(user) {
const [result] = await pool.execute(
'INSERT INTO users (name, email) VALUES (?, ?)',
[user.name, user.email]
);
return result.insertId;
}
// 更新
async function updateUser(id, user) {
await pool.execute(
'UPDATE users SET name = ?, email = ? WHERE id = ?',
[user.name, user.email, id]
);
}
// 删除
async function deleteUser(id) {
await pool.execute('DELETE FROM users WHERE id = ?', [id]);
}
七、环境变量
7.1 dotenv
// 安装
// npm install dotenv
// .env 文件
// PORT=3000
// DB_HOST=localhost
// DB_NAME=myapp
// JWT_SECRET=your-secret-key
// 使用
require('dotenv').config();
const PORT = process.env.PORT || 3000;
const DB_HOST = process.env.DB_HOST;
7.2 环境配置
// config/index.js
require('dotenv').config();
module.exports = {
port: process.env.PORT || 3000,
db: {
host: process.env.DB_HOST || 'localhost',
name: process.env.DB_NAME || 'myapp'
},
jwt: {
secret: process.env.JWT_SECRET,
expiresIn: '7d'
}
};
八、错误处理
8.1 同步错误
try {
const data = fs.readFileSync('file.txt', 'utf8');
} catch (err) {
console.error('读取文件失败:', err.message);
}
8.2 异步错误
// Promise
fsPromises.readFile('file.txt', 'utf8')
.then(data => {
// 处理数据
})
.catch(err => {
console.error('错误:', err);
});
// async/await
async function readFile() {
try {
const data = await fsPromises.readFile('file.txt', 'utf8');
// 处理数据
} catch (err) {
console.error('错误:', err);
}
}
8.3 全局错误处理
// 未捕获的异常
process.on('uncaughtException', (err) => {
console.error('未捕获的异常:', err);
process.exit(1);
});
// 未处理的 Promise 拒绝
process.on('unhandledRejection', (reason, promise) => {
console.error('未处理的 Promise 拒绝:', reason);
});
九、常用工具
9.1 调试
// console 调试
console.log('普通日志');
console.error('错误日志');
console.warn('警告日志');
console.table({ name: '张三', age: 25 });
// debugger
function test() {
debugger; // 断点
console.log('测试');
}
9.2 进程管理
// 获取命令行参数
process.argv.forEach((val, index) => {
console.log(`${index}: ${val}`);
});
// 环境变量
console.log(process.env.NODE_ENV);
// 退出进程
process.exit(0); // 正常退出
process.exit(1); // 错误退出
十、最佳实践
10.1 项目结构
my-app/
├── src/
│ ├── controllers/ # 控制器
│ ├── models/ # 数据模型
│ ├── routes/ # 路由
│ ├── middleware/ # 中间件
│ ├── utils/ # 工具函数
│ └── config/ # 配置文件
├── public/ # 静态文件
├── tests/ # 测试文件
├── .env # 环境变量
├── .gitignore
├── package.json
└── app.js # 入口文件
10.2 代码规范
// 使用 const/let,避免 var
const name = 'Node.js';
let count = 0;
// 使用箭头函数
const add = (a, b) => a + b;
// 使用模板字符串
const message = `Hello, ${name}`;
// 使用解构
const { name, age } = user;
const [first, second] = array;
// 使用 async/await 替代回调
async function fetchData() {
const data = await api.get('/users');
return data;
}
10.3 性能优化
- 使用连接池管理数据库连接
- 合理使用缓存(Redis)
- 压缩响应数据(gzip)
- 使用 CDN 加速静态资源
- 监控内存使用,避免内存泄漏
十一、推荐资源
官方文档:
- Node.js 官方文档:nodejs.org/docs
- npm 文档:docs.npmjs.com
学习资源:
- 《Node.js 实战》
- 《深入浅出 Node.js》
- Node.js 中文网:nodejs.cn
十二、总结
Node.js 核心要点:
异步非阻塞 + 事件驱动 + 丰富生态 = 高效后端开发
核心心法:
Node.js 让 JavaScript 成为全栈语言。 掌握异步编程是 Node.js 开发的关键。
📝 文档信息
- 作者: 阿鑫
- 更新日期: 2026.1