Skip to content

第14章:Node.js 进阶技巧(提升效率)

14.1 环境变量配置(.env文件,区分开发/生产环境)

为什么需要环境变量

  • 区分开发、测试、生产环境的配置
  • 存储敏感信息(如数据库密码、API密钥)
  • 避免硬编码配置信息

实现方法

  1. 安装 dotenv 包

    bash
    npm install dotenv
  2. 创建 .env 文件

    txt
    # 开发环境
    NODE_ENV=development
    PORT=3000
    DB_HOST=localhost
    DB_USER=root
    DB_PASSWORD=password
    DB_NAME=todo_list
    
    # API密钥
    API_KEY=your_api_key
  3. 在应用中加载环境变量

    javascript
    require('dotenv').config();
    
    const port = process.env.PORT || 3000;
    const dbConfig = {
      host: process.env.DB_HOST,
      user: process.env.DB_USER,
      password: process.env.DB_PASSWORD,
      database: process.env.DB_NAME
    };
  4. 添加 .env 到 .gitignore

    # 环境变量文件
    .env

14.2 错误处理进阶(全局错误捕获、接口异常处理)

全局错误处理中间件

javascript
// 全局错误处理中间件
app.use((err, req, res, next) => {
  console.error(err.stack);
  
  // 区分错误类型
  if (err.name === 'ValidationError') {
    return res.status(400).json({ error: err.message });
  }
  
  if (err.code === 'ECONNREFUSED') {
    return res.status(503).json({ error: 'Database connection failed' });
  }
  
  // 默认500错误
  res.status(500).json({ error: 'Internal server error' });
});

异步错误捕获

javascript
// 异步错误捕获中间件
const asyncHandler = (fn) => (req, res, next) => {
  Promise.resolve(fn(req, res, next)).catch(next);
};

// 使用
app.get('/api/users', asyncHandler(async (req, res) => {
  const users = await User.find();
  res.json(users);
}));

自定义错误类

javascript
class AppError extends Error {
  constructor(message, statusCode) {
    super(message);
    this.statusCode = statusCode;
    this.status = statusCode >= 400 && statusCode < 500 ? 'fail' : 'error';
    this.isOperational = true;
    
    Error.captureStackTrace(this, this.constructor);
  }
}

// 使用
if (!user) {
  throw new AppError('User not found', 404);
}

14.3 中间件封装(通用中间件:日志、权限验证)

日志中间件

javascript
const logger = (req, res, next) => {
  const start = Date.now();
  
  // 记录请求信息
  console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
  
  // 监听响应结束
  res.on('finish', () => {
    const duration = Date.now() - start;
    console.log(`[${new Date().toISOString()}] ${req.method} ${req.url} ${res.statusCode} ${duration}ms`);
  });
  
  next();
};

app.use(logger);

权限验证中间件

javascript
const auth = (req, res, next) => {
  const token = req.headers.authorization?.split(' ')[1];
  
  if (!token) {
    return res.status(401).json({ error: 'Access token required' });
  }
  
  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    req.user = decoded;
    next();
  } catch (error) {
    return res.status(401).json({ error: 'Invalid token' });
  }
};

// 保护路由
app.get('/api/profile', auth, (req, res) => {
  res.json({ user: req.user });
});

CORS 中间件

javascript
const cors = (req, res, next) => {
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  
  if (req.method === 'OPTIONS') {
    return res.status(200).end();
  }
  
  next();
};

app.use(cors);

14.4 Node.js 性能优化基础(减少阻塞、合理使用异步)

减少阻塞操作

  1. 使用异步API

    • 优先使用异步版本的文件操作、数据库查询等
    • 避免在主线程中执行CPU密集型任务
  2. 使用工作线程

    javascript
    const { Worker, isMainThread, parentPort } = require('worker_threads');
    
    if (isMainThread) {
      // 主线程
      const worker = new Worker(__filename);
      worker.on('message', result => {
        console.log('Result:', result);
      });
      worker.postMessage({ number: 1000000 });
    } else {
      // 工作线程
      parentPort.on('message', ({ number }) => {
        // 执行CPU密集型任务
        let result = 0;
        for (let i = 0; i < number; i++) {
          result += i;
        }
        parentPort.postMessage(result);
      });
    }

合理使用异步

  1. 并行处理

    javascript
    // 串行处理
    async function serial() {
      const result1 = await fetch('https://api.example.com/data1');
      const result2 = await fetch('https://api.example.com/data2');
      return [result1, result2];
    }
    
    // 并行处理
    async function parallel() {
      const [result1, result2] = await Promise.all([
        fetch('https://api.example.com/data1'),
        fetch('https://api.example.com/data2')
      ]);
      return [result1, result2];
    }
  2. 使用缓存

    javascript
    const cache = new Map();
    
    async function getData(key) {
      if (cache.has(key)) {
        return cache.get(key);
      }
      
      const data = await fetchDataFromDatabase(key);
      cache.set(key, data);
      return data;
    }

优化数据库操作

  1. 使用连接池

    javascript
    const mysql = require('mysql2');
    
    const pool = mysql.createPool({
      host: 'localhost',
      user: 'root',
      password: 'password',
      database: 'test',
      waitForConnections: true,
      connectionLimit: 10,
      queueLimit: 0
    });
  2. 批量操作

    javascript
    // 批量插入
    const users = [
      { name: 'User1', email: 'user1@example.com' },
      { name: 'User2', email: 'user2@example.com' }
    ];
    
    const query = 'INSERT INTO users (name, email) VALUES ?';
    const values = users.map(user => [user.name, user.email]);
    
    pool.query(query, [values], (err, results) => {
      if (err) throw err;
      console.log('Inserted', results.affectedRows, 'rows');
    });

14.5 其他常用框架简介(Koa、Nest.js,了解即可)

Koa

  • 特点:由 Express 团队开发,更轻量、更现代
  • 核心特性
    • 基于 async/await 的中间件机制
    • 内置上下文对象(ctx)
    • 错误处理更优雅
  • 示例
    javascript
    const Koa = require('koa');
    const app = new Koa();
    
    app.use(async (ctx) => {
      ctx.body = 'Hello Koa';
    });
    
    app.listen(3000);

Nest.js

  • 特点:基于 TypeScript,企业级框架
  • 核心特性
    • 依赖注入
    • 模块化架构
    • 支持 GraphQL
    • 内置中间件、守卫、管道等
  • 示例
    typescript
    import { Controller, Get, Module } from '@nestjs/common';
    import { NestFactory } from '@nestjs/core';
    
    @Controller()
    class AppController {
      @Get()
      getHello(): string {
        return 'Hello Nest.js';
      }
    }
    
    @Module({
      controllers: [AppController],
    })
    class AppModule {}
    
    async function bootstrap() {
      const app = await NestFactory.create(AppModule);
      await app.listen(3000);
    }
    
    bootstrap();

选择建议

  • Express:适合快速开发、中小型项目
  • Koa:适合追求简洁、现代的项目
  • Nest.js:适合大型企业级应用、需要严格架构的项目

© 2026 编程马·菜鸟教程 版权所有