Node.js从入门到精通完整指南

发布于:2025-08-09 ⋅ 阅读:(11) ⋅ 点赞:(0)

目录

  1. Node.js基础
  2. 核心模块详解
  3. 文件系统操作
  4. HTTP服务器开发
  5. Express框架
  6. 数据库操作
  7. 异步编程
  8. 中间件开发
  9. 错误处理
  10. 性能优化
  11. 部署与监控
  12. 高级特性

1. Node.js基础

1.1 什么是Node.js

Node.js是基于Chrome V8引擎的JavaScript运行环境,让JavaScript能够在服务器端运行。

特点:

  • 事件驱动、非阻塞I/O模型
  • 单线程但高并发
  • 跨平台
  • 丰富的包生态系统(npm)

1.2 安装与环境配置

# 检查Node.js版本
node --version

# 检查npm版本
npm --version

# 创建新项目
mkdir my-node-app
cd my-node-app
npm init -y

1.3 第一个Node.js程序

// hello.js
console.log('Hello, Node.js!');
console.log('当前Node.js版本:', process.version);
console.log('当前工作目录:', process.cwd());
console.log('命令行参数:', process.argv);
# 运行程序
node hello.js

1.4 模块系统

CommonJS模块 (传统方式):

// math.js - 导出模块
function add(a, b) {
    return a + b;
}

function subtract(a, b) {
    return a - b;
}

// 导出方式1:逐个导出
exports.add = add;
exports.subtract = subtract;

// 导出方式2:整体导出
module.exports = {
    add,
    subtract,
    multiply: (a, b) => a * b
};
// app.js - 导入模块
const math = require('./math');
// 或者使用解构赋值
const { add, subtract } = require('./math');

console.log(math.add(5, 3)); // 8
console.log(subtract(5, 3)); // 2

ES6模块 (现代方式):

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

export function subtract(a, b) {
    return a - b;
}

// 默认导出
export default function multiply(a, b) {
    return a * b;
}
// app.mjs
import multiply, { add, subtract } from './math.mjs';

console.log(add(5, 3)); // 8
console.log(multiply(5, 3)); // 15

2. 核心模块详解

2.1 path模块 - 路径处理

const path = require('path');

// 路径拼接
const fullPath = path.join('/users', 'john', 'documents', 'file.txt');
console.log(fullPath); // /users/john/documents/file.txt

// 路径解析
const filePath = '/home/user/documents/file.txt';
console.log('目录名:', path.dirname(filePath)); // /home/user/documents
console.log('文件名:', path.basename(filePath)); // file.txt
console.log('扩展名:', path.extname(filePath)); // .txt

// 路径规范化
const messyPath = '/home/user/../user/./documents//file.txt';
console.log('规范化路径:', path.normalize(messyPath));
// /home/user/documents/file.txt

2.2 url模块 - URL处理

const url = require('url');

const myUrl = 'https://www.example.com:8080/path/to/resource?name=john&age=30#section1';

// 解析URL
const parsedUrl = url.parse(myUrl, true);
console.log(parsedUrl);
/*
{
  protocol: 'https:',
  host: 'www.example.com:8080',
  hostname: 'www.example.com',
  port: '8080',
  pathname: '/path/to/resource',
  query: { name: 'john', age: '30' },
  hash: '#section1'
}
*/

// 构建URL
const newUrl = url.format({
    protocol: 'https:',
    hostname: 'api.example.com',
    port: 3000,
    pathname: '/users',
    query: { page: 1, limit: 10 }
});
console.log(newUrl); // https://api.example.com:3000/users?page=1&limit=10

2.3 querystring模块 - 查询字符串处理

const querystring = require('querystring');

// 解析查询字符串
const query = 'name=john&age=30&skills=js&skills=node';
const parsed = querystring.parse(query);
console.log(parsed);
// { name: 'john', age: '30', skills: ['js', 'node'] }

// 构建查询字符串
const obj = { name: 'jane', age: 25, city: 'New York' };
const queryStr = querystring.stringify(obj);
console.log(queryStr); // name=jane&age=25&city=New%20York

3. 文件系统操作

3.1 基本文件操作

const fs = require('fs');
const path = require('path');

// 同步读取文件
try {
    const data = fs.readFileSync('example.txt', 'utf8');
    console.log('文件内容:', data);
} catch (error) {
    console.error('读取文件失败:', error.message);
}

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

// Promise方式读取文件
const fsPromises = fs.promises;

async function readFileAsync() {
    try {
        const data = await fsPromises.readFile('example.txt', 'utf8');
        console.log('文件内容:', data);
    } catch (error) {
        console.error('读取文件失败:', error.message);
    }
}

3.2 文件写入操作

const fs = require('fs');

// 写入文件
const content = 'Hello, Node.js File System!';

// 异步写入
fs.writeFile('output.txt', content, 'utf8', (err) => {
    if (err) {
        console.error('写入失败:', err.message);
        return;
    }
    console.log('文件写入成功!');
});

// 追加内容
fs.appendFile('output.txt', '\n追加的内容', 'utf8', (err) => {
    if (err) {
        console.error('追加失败:', err.message);
        return;
    }
    console.log('内容追加成功!');
});

3.3 目录操作

const fs = require('fs');
const path = require('path');

// 创建目录
fs.mkdir('new-directory', { recursive: true }, (err) => {
    if (err) {
        console.error('创建目录失败:', err.message);
        return;
    }
    console.log('目录创建成功!');
});

// 读取目录
fs.readdir('.', (err, files) => {
    if (err) {
        console.error('读取目录失败:', err.message);
        return;
    }
    
    console.log('目录内容:');
    files.forEach(file => {
        const filePath = path.join('.', file);
        const stats = fs.statSync(filePath);
        
        if (stats.isDirectory()) {
            console.log(`📁 ${file}/`);
        } else {
            console.log(`📄 ${file} (${stats.size} bytes)`);
        }
    });
});

3.4 文件流操作

const fs = require('fs');
const path = require('path');

// 创建可读流
const readStream = fs.createReadStream('large-file.txt', {
    encoding: 'utf8',
    highWaterMark: 1024 // 缓冲区大小
});

// 创建可写流
const writeStream = fs.createWriteStream('output-stream.txt');

// 流事件处理
readStream.on('data', (chunk) => {
    console.log(`读取到 ${chunk.length} 字节数据`);
    writeStream.write(chunk);
});

readStream.on('end', () => {
    console.log('文件读取完成');
    writeStream.end();
});

readStream.on('error', (err) => {
    console.error('读取错误:', err.message);
});

// 使用管道简化流操作
const inputStream = fs.createReadStream('input.txt');
const outputStream = fs.createWriteStream('output-pipe.txt');

inputStream.pipe(outputStream);

4. HTTP服务器开发

4.1 基本HTTP服务器

const http = require('http');
const url = require('url');
const querystring = require('querystring');

// 创建HTTP服务器
const server = http.createServer((req, res) => {
    const parsedUrl = url.parse(req.url, true);
    const method = req.method;
    const pathname = parsedUrl.pathname;
    const query = parsedUrl.query;
    
    // 设置响应头
    res.setHeader('Content-Type', 'application/json; charset=utf-8');
    res.setHeader('Access-Control-Allow-Origin', '*');
    
    console.log(`${method} ${pathname}`);
    
    // 路由处理
    if (pathname === '/' && method === 'GET') {
        res.statusCode = 200;
        res.end(JSON.stringify({
            message: '欢迎使用Node.js HTTP服务器!',
            timestamp: new Date().toISOString()
        }));
    } else if (pathname === '/api/users' && method === 'GET') {
        const users = [
            { id: 1, name: 'Alice', email: 'alice@example.com' },
            { id: 2, name: 'Bob', email: 'bob@example.com' }
        ];
        
        res.statusCode = 200;
        res.end(JSON.stringify({ users }));
    } else if (pathname === '/api/users' && method === 'POST') {
        let body = '';
        
        req.on('data', chunk => {
            body += chunk.toString();
        });
        
        req.on('end', () => {
            try {
                const userData = JSON.parse(body);
                // 这里应该保存到数据库
                res.statusCode = 201;
                res.end(JSON.stringify({
                    message: '用户创建成功',
                    user: { id: Date.now(), ...userData }
                }));
            } catch (error) {
                res.statusCode = 400;
                res.end(JSON.stringify({
                    error: '无效的JSON数据'
                }));
            }
        });
    } else {
        res.statusCode = 404;
        res.end(JSON.stringify({
            error: '页面未找到'
        }));
    }
});

// 启动服务器
const PORT = process.env.PORT || 3000;
server.listen(PORT, () => {
    console.log(`服务器运行在 http://localhost:${PORT}`);
});

// 优雅关闭
process.on('SIGTERM', () => {
    console.log('收到SIGTERM信号,正在关闭服务器...');
    server.close(() => {
        console.log('服务器已关闭');
        process.exit(0);
    });
});

4.2 HTTPS服务器

const https = require('https');
const fs = require('fs');

// SSL证书配置
const options = {
    key: fs.readFileSync('private-key.pem'),
    cert: fs.readFileSync('certificate.pem')
};

const server = https.createServer(options, (req, res) => {
    res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
    res.end(`
        <h1>HTTPS服务器</h1>
        <p>这是一个安全的HTTPS连接</p>
        <p>当前时间: ${new Date().toLocaleString()}</p>
    `);
});

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

5. Express框架

5.1 Express基础

// 首先安装Express: npm install express

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

// 中间件配置
app.use(express.json()); // 解析JSON请求体
app.use(express.urlencoded({ extended: true })); // 解析URL编码请求体
app.use(express.static('public')); // 静态文件服务

// 基本路由
app.get('/', (req, res) => {
    res.json({
        message: '欢迎使用Express!',
        version: '1.0.0'
    });
});

// 路由参数
app.get('/users/:id', (req, res) => {
    const userId = req.params.id;
    res.json({
        message: `获取用户信息`,
        userId: userId
    });
});

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

// POST路由
app.post('/users', (req, res) => {
    const { name, email } = req.body;
    
    if (!name || !email) {
        return res.status(400).json({
            error: '姓名和邮箱不能为空'
        });
    }
    
    // 模拟保存到数据库
    const user = {
        id: Date.now(),
        name,
        email,
        createdAt: new Date()
    };
    
    res.status(201).json({
        message: '用户创建成功',
        user
    });
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
    console.log(`Express服务器运行在端口 ${PORT}`);
});

5.2 Express路由模块化

// routes/users.js
const express = require('express');
const router = express.Router();

// 用户数据模拟
let users = [
    { id: 1, name: 'Alice', email: 'alice@example.com' },
    { id: 2, name: 'Bob', email: 'bob@example.com' }
];

// 获取所有用户
router.get('/', (req, res) => {
    res.json({ users });
});

// 获取单个用户
router.get('/:id', (req, res) => {
    const user = users.find(u => u.id === parseInt(req.params.id));
    if (!user) {
        return res.status(404).json({ error: '用户不存在' });
    }
    res.json({ user });
});

// 创建用户
router.post('/', (req, res) => {
    const { name, email } = req.body;
    const user = {
        id: Math.max(...users.map(u => u.id)) + 1,
        name,
        email
    };
    users.push(user);
    res.status(201).json({ user });
});

// 更新用户
router.put('/:id', (req, res) => {
    const userId = parseInt(req.params.id);
    const userIndex = users.findIndex(u => u.id === userId);
    
    if (userIndex === -1) {
        return res.status(404).json({ error: '用户不存在' });
    }
    
    users[userIndex] = { ...users[userIndex], ...req.body };
    res.json({ user: users[userIndex] });
});

// 删除用户
router.delete('/:id', (req, res) => {
    const userId = parseInt(req.params.id);
    const userIndex = users.findIndex(u => u.id === userId);
    
    if (userIndex === -1) {
        return res.status(404).json({ error: '用户不存在' });
    }
    
    const deletedUser = users.splice(userIndex, 1)[0];
    res.json({ message: '用户删除成功', user: deletedUser });
});

module.exports = router;
// app.js - 使用路由模块
const express = require('express');
const usersRouter = require('./routes/users');

const app = express();

app.use(express.json());
app.use('/api/users', usersRouter);

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

5.3 Express中间件

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

// 日志中间件
const logger = (req, res, next) => {
    const timestamp = new Date().toISOString();
    console.log(`[${timestamp}] ${req.method} ${req.url}`);
    next(); // 传递控制权给下一个中间件
};

// 认证中间件
const authenticate = (req, res, next) => {
    const token = req.headers.authorization;
    
    if (!token) {
        return res.status(401).json({ error: '缺少认证令牌' });
    }
    
    // 模拟令牌验证
    if (token !== 'Bearer valid-token') {
        return res.status(401).json({ error: '无效的令牌' });
    }
    
    req.user = { id: 1, name: 'Alice' }; // 设置用户信息
    next();
};

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

// 应用中间件
app.use(logger);
app.use(express.json());

// 公开路由
app.get('/', (req, res) => {
    res.json({ message: '欢迎访问API' });
});

// 需要认证的路由
app.get('/profile', authenticate, (req, res) => {
    res.json({
        message: '用户资料',
        user: req.user
    });
});

// 触发错误的路由(用于测试错误处理)
app.get('/error', (req, res, next) => {
    const error = new Error('这是一个测试错误');
    error.type = 'validation';
    next(error);
});

// 应用错误处理中间件(必须放在最后)
app.use(errorHandler);

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

6. 数据库操作

6.1 MongoDB集成(使用Mongoose)

// 首先安装: npm install mongoose

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

// 连接MongoDB
mongoose.connect('mongodb://localhost:27017/nodeapp', {
    useNewUrlParser: true,
    useUnifiedTopology: true
})
.then(() => console.log('MongoDB连接成功'))
.catch(err => console.error('MongoDB连接失败:', err));

// 定义用户模式
const userSchema = new mongoose.Schema({
    name: {
        type: String,
        required: [true, '姓名不能为空'],
        trim: true,
        maxlength: [50, '姓名不能超过50个字符']
    },
    email: {
        type: String,
        required: [true, '邮箱不能为空'],
        unique: true,
        lowercase: true,
        match: [/^\w+@\w+\.\w+$/, '邮箱格式不正确']
    },
    age: {
        type: Number,
        min: [0, '年龄不能为负数'],
        max: [120, '年龄不能超过120']
    },
    createdAt: {
        type: Date,
        default: Date.now
    }
});

// 添加索引
userSchema.index({ email: 1 }, { unique: true });

// 实例方法
userSchema.methods.getFullInfo = function() {
    return `${this.name} (${this.email})`;
};

// 静态方法
userSchema.statics.findByEmail = function(email) {
    return this.findOne({ email });
};

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

const app = express();
app.use(express.json());

// 创建用户
app.post('/api/users', async (req, res) => {
    try {
        const user = new User(req.body);
        await user.save();
        res.status(201).json({
            message: '用户创建成功',
            user
        });
    } catch (error) {
        if (error.name === 'ValidationError') {
            const errors = Object.values(error.errors).map(e => e.message);
            return res.status(400).json({ errors });
        }
        if (error.code === 11000) {
            return res.status(400).json({ error: '邮箱已存在' });
        }
        res.status(500).json({ error: '服务器错误' });
    }
});

// 获取所有用户
app.get('/api/users', async (req, res) => {
    try {
        const { page = 1, limit = 10, search } = req.query;
        const query = search ? 
            { $or: [
                { name: new RegExp(search, 'i') },
                { email: new RegExp(search, 'i') }
            ]} : {};
        
        const users = await User.find(query)
            .limit(limit * 1)
            .skip((page - 1) * limit)
            .sort({ createdAt: -1 });
            
        const total = await User.countDocuments(query);
        
        res.json({
            users,
            pagination: {
                page: parseInt(page),
                limit: parseInt(limit),
                total,
                pages: Math.ceil(total / limit)
            }
        });
    } catch (error) {
        res.status(500).json({ error: '服务器错误' });
    }
});

// 获取单个用户
app.get('/api/users/:id', async (req, res) => {
    try {
        const user = await User.findById(req.params.id);
        if (!user) {
            return res.status(404).json({ error: '用户不存在' });
        }
        res.json({ user });
    } catch (error) {
        res.status(500).json({ error: '服务器错误' });
    }
});

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

6.2 MySQL集成(使用mysql2)

// 首先安装: npm install mysql2

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

// 创建数据库连接池
const pool = mysql.createPool({
    host: 'localhost',
    user: 'root',
    password: 'password',
    database: 'nodeapp',
    waitForConnections: true,
    connectionLimit: 10,
    queueLimit: 0
});

// 数据库初始化
async function initDatabase() {
    try {
        await pool.execute(`
            CREATE TABLE IF NOT EXISTS users (
                id INT AUTO_INCREMENT PRIMARY KEY,
                name VARCHAR(50) NOT NULL,
                email VARCHAR(100) NOT NULL UNIQUE,
                age INT,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
        `);
        console.log('数据库表创建成功');
    } catch (error) {
        console.error('数据库初始化失败:', error);
    }
}

initDatabase();

const app = express();
app.use(express.json());

// 创建用户
app.post('/api/users', async (req, res) => {
    const { name, email, age } = req.body;
    
    try {
        const [result] = await pool.execute(
            'INSERT INTO users (name, email, age) VALUES (?, ?, ?)',
            [name, email, age]
        );
        
        const [users] = await

网站公告

今日签到

点亮在社区的每一天
去签到