后端-Node基础知识

3 阅读6分钟

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 常用包

包名用途
expressWeb 框架
nodemon开发时自动重启
dotenv环境变量管理
cors跨域处理
body-parser请求体解析
mongooseMongoDB 驱动
mysql2MySQL 驱动
axiosHTTP 客户端
bcrypt密码加密
jsonwebtokenJWT 认证

五、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 实战》
  • 《深入浅出 Node.js》
  • Node.js 中文网:nodejs.cn

十二、总结

Node.js 核心要点:

异步非阻塞 + 事件驱动 + 丰富生态 = 高效后端开发

核心心法:

Node.js 让 JavaScript 成为全栈语言。 掌握异步编程是 Node.js 开发的关键。


📝 文档信息

  • 作者: 阿鑫
  • 更新日期: 2026.1