Node.js 开发教程

1. 简介

Node.js 是一个基于 Chrome V8 JavaScript 引擎的 JavaScript 运行时环境。它允许你在服务器端运行 JavaScript 代码,为全栈 JavaScript 开发提供了可能。

2. 安装和环境配置

安装 Node.js

官方网站 下载并安装 Node.js。安装完成后,可以通过以下命令验证:

node --version
npm --version

初始化项目

mkdir my-node-app
cd my-node-app
npm init -y

3. 核心模块

文件系统模块 (fs)

Node.js 提供了强大的文件系统操作能力:

const fs = require('fs');

// 读取文件
fs.readFile('example.txt', 'utf8', (err, data) => {
    if (err) {
        console.error('读取文件失败:', err);
        return;
    }
    console.log('文件内容:', data);
});

// 写入文件
fs.writeFile('output.txt', '你好,Node.js!', (err) => {
    if (err) {
        console.error('写入文件失败:', err);
        return;
    }
    console.log('文件写入成功!');
});

HTTP 模块

创建简单的 HTTP 服务器:

const http = require('http');

const server = http.createServer((req, res) => {
    res.writeHead(200, {'Content-Type': 'text/html; charset=utf-8'});
    res.end('你好,这是我的第一个 Node.js 服务器!');
});

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

Path 模块

处理文件路径:

const path = require('path');

console.log(path.join(__dirname, 'files', 'data.txt'));
console.log(path.extname('example.txt')); // .txt
console.log(path.basename('/users/john/documents/file.txt')); // file.txt

4. NPM 包管理

安装包

// 本地安装
npm install express

// 全局安装
npm install -g nodemon

// 安装开发依赖
npm install --save-dev jest

创建 package.json

{
    "name": "my-node-app",
    "version": "1.0.0",
    "description": "我的第一个 Node.js 应用",
    "main": "app.js",
    "scripts": {
        "start": "node app.js",
        "dev": "nodemon app.js",
        "test": "jest"
    },
    "dependencies": {
        "express": "^4.18.2"
    },
    "devDependencies": {
        "nodemon": "^2.0.20"
    }
}

5. Express 框架

基本使用

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

// 中间件
app.use(express.json());
app.use(express.static('public'));

// 路由
app.get('/', (req, res) => {
    res.send('欢迎来到 Express 应用!');
});

app.get('/api/users', (req, res) => {
    res.json([
        { id: 1, name: '张三', email: 'zhangsan@example.com' },
        { id: 2, name: '李四', email: 'lisi@example.com' }
    ]);
});

app.post('/api/users', (req, res) => {
    const { name, email } = req.body;
    // 处理创建用户的逻辑
    res.status(201).json({ message: '用户创建成功', id: 3, name, email });
});

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

路由参数

// URL 参数
app.get('/users/:id', (req, res) => {
    const userId = req.params.id;
    res.json({ id: userId, name: '用户' + userId });
});

// 查询参数
app.get('/search', (req, res) => {
    const { q, page = 1 } = req.query;
    res.json({ query: q, page: parseInt(page) });
});

6. 中间件

自定义中间件

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

app.use(logger);

// 错误处理中间件
const errorHandler = (err, req, res, next) => {
    console.error(err.stack);
    res.status(500).json({ error: '服务器内部错误' });
};

app.use(errorHandler);

7. 数据库操作

MongoDB 连接 (使用 Mongoose)

const mongoose = require('mongoose');

// 连接数据库
mongoose.connect('mongodb://localhost:27017/myapp', {
    useNewUrlParser: true,
    useUnifiedTopology: true
});

// 定义模型
const userSchema = new mongoose.Schema({
    name: { type: String, required: true },
    email: { type: String, required: true, unique: true },
    createdAt: { type: Date, default: Date.now }
});

const User = mongoose.model('User', userSchema);

// 使用模型
app.post('/api/users', async (req, res) => {
    try {
        const user = new User(req.body);
        await user.save();
        res.status(201).json(user);
    } catch (error) {
        res.status(400).json({ error: error.message });
    }
});

MySQL 连接 (使用 mysql2)

const mysql = require('mysql2/promise');

const connection = mysql.createConnection({
    host: 'localhost',
    user: 'root',
    password: 'password',
    database: 'myapp'
});

app.get('/api/users', async (req, res) => {
    try {
        const [rows] = await connection.execute('SELECT * FROM users');
        res.json(rows);
    } catch (error) {
        res.status(500).json({ error: error.message });
    }
});

8. 异步编程

Promise 和 async/await

// Promise 方式
function readFilePromise(filename) {
    return new Promise((resolve, reject) => {
        fs.readFile(filename, 'utf8', (err, data) => {
            if (err) reject(err);
            else resolve(data);
        });
    });
}

// async/await 方式
async function processFile() {
    try {
        const data = await readFilePromise('example.txt');
        console.log('文件内容:', data);
    } catch (error) {
        console.error('读取文件失败:', error);
    }
}

9. 环境变量和配置

使用 dotenv

// 安装 dotenv
npm install dotenv

// .env 文件
PORT=3000
DB_HOST=localhost
DB_USER=root
DB_PASSWORD=secret
JWT_SECRET=your-secret-key

// app.js
require('dotenv').config();

const port = process.env.PORT || 3000;
const dbHost = process.env.DB_HOST;

app.listen(port, () => {
    console.log(`服务器运行在端口 ${port}`);
});

10. 测试

使用 Jest

// math.js
function add(a, b) {
    return a + b;
}

function multiply(a, b) {
    return a * b;
}

module.exports = { add, multiply };

// math.test.js
const { add, multiply } = require('./math');

test('加法运算', () => {
    expect(add(2, 3)).toBe(5);
    expect(add(-1, 1)).toBe(0);
});

test('乘法运算', () => {
    expect(multiply(3, 4)).toBe(12);
    expect(multiply(0, 5)).toBe(0);
});

11. 部署

PM2 进程管理

// 安装 PM2
npm install -g pm2

// 启动应用
pm2 start app.js --name "my-app"

// 查看状态
pm2 status

// 重启应用
pm2 restart my-app

// 停止应用
pm2 stop my-app

Docker 容器化

# Dockerfile
FROM node:18-alpine

WORKDIR /app

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

COPY . .

EXPOSE 3000

CMD ["node", "app.js"]

12. 安全性

常见安全措施

const helmet = require('helmet');
const rateLimit = require('express-rate-limit');

// 安全头部
app.use(helmet());

// 限制请求频率
const limiter = rateLimit({
    windowMs: 15 * 60 * 1000, // 15分钟
    max: 100 // 最多100个请求
});
app.use(limiter);

// 输入验证
const { body, validationResult } = require('express-validator');

app.post('/api/users', [
    body('email').isEmail(),
    body('name').isLength({ min: 2, max: 50 })
], (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
        return res.status(400).json({ errors: errors.array() });
    }
    // 处理请求
});

13. 性能优化

缓存策略

const redis = require('redis');
const client = redis.createClient();

// 缓存中间件
const cache = (duration) => {
    return async (req, res, next) => {
        const key = req.originalUrl;
        const cached = await client.get(key);
        
        if (cached) {
            return res.json(JSON.parse(cached));
        }
        
        res.sendResponse = res.json;
        res.json = (body) => {
            client.setex(key, duration, JSON.stringify(body));
            res.sendResponse(body);
        };
        
        next();
    };
};

app.get('/api/users', cache(300), (req, res) => {
    // 获取用户数据
});

总结

Node.js 是一个强大的 JavaScript 运行时环境,特别适合构建高性能的网络应用。通过学习核心模块、Express 框架、数据库操作、异步编程等内容,你可以构建功能完整的后端应用。

继续学习的方向包括:微服务架构、GraphQL、WebSocket 实时通信、性能监控等高级主题。