Skip to content

Node.js技术栈

Node.js基础

什么是Node.js

Node.js是一个基于Chrome V8引擎的JavaScript运行时环境,让JavaScript可以在服务器端运行。它具有事件驱动、非阻塞I/O的特点,特别适合构建高性能的网络应用。

核心特性

  • 事件驱动:基于事件循环模型,高效处理并发请求
  • 非阻塞I/O:异步处理I/O操作,不会阻塞主线程
  • 单线程:主线程处理事件循环,工作线程处理CPU密集型任务
  • 跨平台:支持Windows、macOS、Linux等操作系统

应用场景

  • Web服务器开发
  • API服务构建
  • 实时应用(聊天、游戏)
  • 命令行工具
  • 构建工具和打包工具

核心模块

文件系统 (fs)

javascript
// 异步读取文件
const fs = require('fs').promises;

async function readFile() {
  try {
    const data = await fs.readFile('file.txt', 'utf8');
    console.log(data);
  } catch (error) {
    console.error('读取文件失败:', error);
  }
}

HTTP模块

javascript
const http = require('http');

const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('Hello World\n');
});

server.listen(3000, () => {
  console.log('服务器运行在 http://localhost:3000/');
});

事件模块 (events)

javascript
const EventEmitter = require('events');

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter();

myEmitter.on('event', (arg) => {
  console.log('事件触发:', arg);
});

myEmitter.emit('event', 'Hello World');

Web框架

Express.js

Express是最流行的Node.js Web框架,简单易用,适合快速开发。

基础使用

javascript
const express = require('express');
const app = express();

// 中间件
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// 路由
app.get('/', (req, res) => {
  res.send('Hello Express!');
});

app.post('/api/users', (req, res) => {
  const user = req.body;
  // 处理用户数据
  res.json({ success: true, user });
});

app.listen(3000, () => {
  console.log('Express服务器运行在端口 3000');
});

中间件开发

javascript
// 自定义中间件
const logger = (req, res, next) => {
  console.log(`${new Date().toISOString()} - ${req.method} ${req.url}`);
  next();
};

app.use(logger);

Koa.js

Koa是Express团队开发的新一代Web框架,基于async/await,提供更优雅的错误处理。

基础使用

javascript
const Koa = require('koa');
const Router = require('@koa/router');

const app = new Koa();
const router = new Router();

// 中间件
app.use(async (ctx, next) => {
  const start = Date.now();
  await next();
  const ms = Date.now() - start;
  ctx.set('X-Response-Time', `${ms}ms`);
});

// 路由
router.get('/', async (ctx) => {
  ctx.body = 'Hello Koa!';
});

router.post('/api/users', async (ctx) => {
  const user = ctx.request.body;
  // 处理用户数据
  ctx.body = { success: true, user };
});

app.use(router.routes());
app.use(router.allowedMethods());

app.listen(3000);

Fastify

Fastify是一个专注于提供最高效率和速度的Web框架。

javascript
const fastify = require('fastify')({ logger: true });

// 路由
fastify.get('/', async (request, reply) => {
  return { hello: 'world' };
});

fastify.post('/api/users', async (request, reply) => {
  const user = request.body;
  return { success: true, user };
});

// 启动服务器
const start = async () => {
  try {
    await fastify.listen({ port: 3000 });
  } catch (err) {
    fastify.log.error(err);
    process.exit(1);
  }
};

start();

包管理

npm (Node Package Manager)

npm是Node.js的默认包管理器,用于安装和管理依赖。

常用命令

bash
# 初始化项目
npm init

# 安装依赖
npm install express
npm install --save-dev nodemon

# 运行脚本
npm start
npm run dev

# 更新依赖
npm update
npm audit fix

yarn

yarn是Facebook开发的包管理器,提供更快的安装速度和更好的依赖锁定。

bash
# 安装yarn
npm install -g yarn

# 安装依赖
yarn add express
yarn add --dev nodemon

# 运行脚本
yarn start
yarn dev

pnpm

pnpm是一个快速、节省磁盘空间的包管理器。

bash
# 安装pnpm
npm install -g pnpm

# 安装依赖
pnpm add express
pnpm add -D nodemon

# 运行脚本
pnpm start
pnpm dev

异步编程

Promise

Promise是处理异步操作的标准方式。

javascript
function fetchData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const data = { id: 1, name: 'John' };
      resolve(data);
    }, 1000);
  });
}

fetchData()
  .then(data => console.log(data))
  .catch(error => console.error(error));

async/await

async/await是Promise的语法糖,让异步代码看起来像同步代码。

javascript
async function fetchUserData() {
  try {
    const user = await fetchData();
    console.log(user);
  } catch (error) {
    console.error('获取用户数据失败:', error);
  }
}

fetchUserData();

错误处理

全局错误处理

javascript
process.on('uncaughtException', (error) => {
  console.error('未捕获的异常:', error);
  process.exit(1);
});

process.on('unhandledRejection', (reason, promise) => {
  console.error('未处理的Promise拒绝:', reason);
  process.exit(1);
});

中间件错误处理

javascript
// Express错误处理中间件
app.use((error, req, res, next) => {
  console.error(error.stack);
  res.status(500).send('服务器内部错误');
});

// Koa错误处理
app.use(async (ctx, next) => {
  try {
    await next();
  } catch (err) {
    ctx.status = err.status || 500;
    ctx.body = { error: err.message };
    ctx.app.emit('error', err, ctx);
  }
});

性能优化

内存管理

javascript
// 避免内存泄漏
const cache = new Map();

// 定期清理缓存
setInterval(() => {
  cache.clear();
}, 60000); // 每分钟清理一次

集群模式

javascript
const cluster = require('cluster');
const numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  // 主进程:创建工作进程
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }
  
  cluster.on('exit', (worker, code, signal) => {
    console.log(`工作进程 ${worker.process.pid} 已退出`);
    cluster.fork(); // 重启工作进程
  });
} else {
  // 工作进程:运行应用
  require('./app.js');
}

测试

Jest测试框架

javascript
// user.test.js
const { createUser, getUser } = require('./user');

describe('用户模块', () => {
  test('应该创建新用户', async () => {
    const userData = { name: 'John', email: '[email protected]' };
    const user = await createUser(userData);
    
    expect(user.name).toBe('John');
    expect(user.email).toBe('[email protected]');
  });
  
  test('应该获取用户信息', async () => {
    const user = await getUser(1);
    expect(user).toBeDefined();
  });
});

Supertest API测试

javascript
const request = require('supertest');
const app = require('./app');

describe('API测试', () => {
  test('GET / 应该返回200', async () => {
    const response = await request(app).get('/');
    expect(response.status).toBe(200);
  });
  
  test('POST /api/users 应该创建用户', async () => {
    const userData = { name: 'John', email: '[email protected]' };
    const response = await request(app)
      .post('/api/users')
      .send(userData);
    
    expect(response.status).toBe(201);
    expect(response.body.success).toBe(true);
  });
});

部署

PM2进程管理

javascript
// ecosystem.config.js
module.exports = {
  apps: [{
    name: 'my-app',
    script: './app.js',
    instances: 'max',
    exec_mode: 'cluster',
    env: {
      NODE_ENV: 'development'
    },
    env_production: {
      NODE_ENV: 'production'
    }
  }]
};

Docker容器化

dockerfile
# Dockerfile
FROM node:18-alpine

WORKDIR /app

COPY package*.json ./
RUN npm ci --only=production

COPY . .

EXPOSE 3000

CMD ["npm", "start"]

最佳实践

项目结构

project/
├── src/
│   ├── controllers/
│   ├── services/
│   ├── models/
│   ├── middleware/
│   ├── routes/
│   └── utils/
├── tests/
├── config/
├── logs/
├── package.json
└── README.md

环境配置

javascript
// config/index.js
require('dotenv').config();

module.exports = {
  port: process.env.PORT || 3000,
  database: {
    url: process.env.DATABASE_URL,
    pool: {
      min: parseInt(process.env.DB_POOL_MIN) || 2,
      max: parseInt(process.env.DB_POOL_MAX) || 10
    }
  },
  jwt: {
    secret: process.env.JWT_SECRET,
    expiresIn: process.env.JWT_EXPIRES_IN || '24h'
  }
};

日志记录

javascript
const winston = require('winston');

const logger = winston.createLogger({
  level: 'info',
  format: winston.format.combine(
    winston.format.timestamp(),
    winston.format.json()
  ),
  transports: [
    new winston.transports.File({ filename: 'error.log', level: 'error' }),
    new winston.transports.File({ filename: 'combined.log' })
  ]
});

if (process.env.NODE_ENV !== 'production') {
  logger.add(new winston.transports.Console({
    format: winston.format.simple()
  }));
}

Node.js技术栈是现代后端开发的重要组成部分,掌握这些技术将帮助你构建高性能、可扩展的Web应用。