Nodejs教程

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时环境,让 JavaScript 可以运行在服务器端。本教程将带你从基础到高级全面学习 Node.js。

目录

  1. Node.js 简介
  2. 安装与环境配置
  3. Node.js 基础
  4. 模块系统
  5. 文件系统操作
  6. HTTP 模块与 Web 服务器
  7. NPM 包管理器
  8. Express 框架
  9. 数据库连接
  10. 异步编程
  11. 调试与测试
  12. 部署与性能优化

Node.js 简介

Node.js 是一个开源、跨平台的 JavaScript 运行时环境,具有以下特点:

  • 基于 Chrome V8 JavaScript 引擎
  • 事件驱动、非阻塞 I/O 模型
  • 轻量且高效
  • 单线程但支持高并发
  • 拥有庞大的生态系统 (npm)

Node.js 应用场景

  • Web 服务器开发
  • RESTful API 服务
  • 实时应用 (如聊天室)
  • 命令行工具
  • 微服务架构
  • 脚本任务自动化

安装与环境配置

安装 Node.js

  1. 访问 Node.js 官网
  2. 下载 LTS (长期支持) 版本
  3. 按照安装向导完成安装

验证安装:

node -v
npm -v

使用 nvm (Node Version Manager)

对于需要多版本切换的用户,推荐使用 nvm:

# 安装 nvm (Linux/macOS)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash

# Windows 用户可使用 nvm-windows

常用命令:

nvm install 14.17.0  # 安装指定版本
nvm use 14.17.0      # 使用指定版本
nvm ls               # 查看已安装版本

Node.js 基础

第一个 Node.js 程序

创建 app.js 文件:

console.log("Hello, Node.js!");

运行:

node app.js

REPL 交互式环境

Node.js 提供了类似浏览器控制台的 REPL (Read-Eval-Print Loop) 环境:

node
> 1 + 1
2
> const fs = require('fs')
undefined
> .exit

全局对象

Node.js 中的全局对象是 global,类似于浏览器中的 window

常用全局变量/函数:

  • __filename - 当前模块的文件名
  • __dirname - 当前模块的目录名
  • process - 进程对象
  • console - 控制台对象
  • setTimeout/setInterval - 定时器
  • require() - 导入模块
  • module/exports - 模块系统

模块系统

Node.js 使用 CommonJS 模块系统。

创建模块

math.js:

function add(a, b) {
  return a + b;
}

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

module.exports = {
  add,
  subtract
};

使用模块

app.js:

const math = require('./math');

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

核心模块

Node.js 内置了许多核心模块,无需安装即可使用:

  • fs - 文件系统
  • path - 路径处理
  • http - HTTP 服务器/客户端
  • os - 操作系统信息
  • events - 事件处理
  • stream - 流处理

示例:

const os = require('os');
console.log(os.platform());  // 输出操作系统平台

文件系统操作

fs 模块提供了文件操作的 API,包括同步和异步版本。

读取文件

异步读取:

const fs = require('fs');

fs.readFile('example.txt', 'utf8', (err, data) => {
  if (err) throw err;
  console.log(data);
});

同步读取:

const data = fs.readFileSync('example.txt', 'utf8');
console.log(data);

写入文件

异步写入:

fs.writeFile('example.txt', 'Hello Node.js', (err) => {
  if (err) throw err;
  console.log('File written');
});

同步写入:

fs.writeFileSync('example.txt', 'Hello Node.js');

其他常用操作

// 检查文件是否存在
fs.existsSync('example.txt');

// 获取文件信息
fs.stat('example.txt', (err, stats) => {
  console.log(stats.isFile());
  console.log(stats.size);
});

// 重命名文件
fs.rename('old.txt', 'new.txt', (err) => {});

// 删除文件
fs.unlink('file.txt', (err) => {});

// 创建目录
fs.mkdir('newdir', (err) => {});

// 读取目录
fs.readdir('./', (err, files) => {
  console.log(files);
});

HTTP 模块与 Web 服务器

创建基本 HTTP 服务器

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('Server running at http://localhost:3000/');
});

处理不同路由

const server = http.createServer((req, res) => {
  if (req.url === '/') {
    res.writeHead(200, {'Content-Type': 'text/html'});
    res.end('<h1>Home Page</h1>');
  } else if (req.url === '/about') {
    res.writeHead(200, {'Content-Type': 'text/html'});
    res.end('<h1>About Page</h1>');
  } else {
    res.writeHead(404, {'Content-Type': 'text/html'});
    res.end('<h1>404 Not Found</h1>');
  }
});

处理 POST 请求

const server = http.createServer((req, res) => {
  if (req.method === 'POST' && req.url === '/data') {
    let body = '';

    req.on('data', chunk => {
      body += chunk.toString();
    });

    req.on('end', () => {
      console.log(JSON.parse(body));
      res.end('Data received');
    });
  }
});

NPM 包管理器

npm (Node Package Manager) 是 Node.js 的包管理工具。

常用命令

npm init                  # 初始化项目,创建 package.json
npm install package-name  # 安装包
npm install -g package-name # 全局安装
npm install --save package-name # 安装并添加到 dependencies
npm install --save-dev package-name # 安装并添加到 devDependencies
npm update package-name   # 更新包
npm uninstall package-name # 卸载包
npm list                  # 查看已安装的包
npm search package-name   # 搜索包
npm run script-name       # 运行 package.json 中的脚本

package.json 示例

{
  "name": "my-app",
  "version": "1.0.0",
  "description": "A sample Node.js application",
  "main": "app.js",
  "scripts": {
    "start": "node app.js",
    "dev": "nodemon app.js",
    "test": "jest"
  },
  "dependencies": {
    "express": "^4.17.1"
  },
  "devDependencies": {
    "nodemon": "^2.0.7"
  }
}

Express 框架

Express 是最流行的 Node.js Web 框架。

安装 Express

npm install express

基本应用

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

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

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`);
});

路由处理

// 基本路由
app.get('/about', (req, res) => {
  res.send('About Page');
});

// 路由参数
app.get('/users/:userId', (req, res) => {
  res.send(`User ID: ${req.params.userId}`);
});

// 查询参数
app.get('/search', (req, res) => {
  res.send(`Search query: ${req.query.q}`);
});

// POST 请求
app.post('/login', (req, res) => {
  // 处理登录逻辑
  res.send('Login successful');
});

中间件

Express 的核心是中间件机制。

// 应用级中间件
app.use((req, res, next) => {
  console.log('Time:', Date.now());
  next();
});

// 路由级中间件
app.use('/admin', (req, res, next) => {
  // 验证管理员权限
  next();
});

// 内置中间件
app.use(express.json());       // 解析 JSON 请求体
app.use(express.urlencoded({ extended: true })); // 解析表单数据

// 第三方中间件
const morgan = require('morgan');
app.use(morgan('dev'));  // 日志记录

// 错误处理中间件
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).send('Something broke!');
});

静态文件服务

app.use(express.static('public'));

// 现在可以访问 public 目录下的文件
// 例如 public/images/logo.png 可以通过 /images/logo.png 访问

模板引擎

Express 支持多种模板引擎,如 EJS、Pug、Handlebars 等。

安装 EJS:

npm install ejs

配置和使用:

app.set('view engine', 'ejs');
app.set('views', './views');  // 默认就是 ./views

app.get('/', (req, res) => {
  res.render('index', { title: 'Home Page', message: 'Welcome!' });
});

views/index.ejs:

<!DOCTYPE html>
<html>
<head>
  <title><%= title %></title>
</head>
<body>
  <h1><%= message %></h1>
</body>
</html>

运行 HTML

数据库连接

MongoDB (使用 Mongoose)

安装 Mongoose:

npm install mongoose

连接和使用:

const mongoose = require('mongoose');

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

// 定义模型
const User = mongoose.model('User', {
  name: String,
  email: String,
  age: Number
});

// 创建文档
const user = new User({
  name: 'John Doe',
  email: 'john@example.com',
  age: 30
});

// 保存到数据库
user.save()
  .then(() => console.log('User saved'))
  .catch(err => console.error(err));

// 查询文档
User.find({ age: { $gt: 25 } })
  .then(users => console.log(users));

MySQL

安装 MySQL 驱动:

npm install mysql2

连接和使用:

const mysql = require('mysql2');

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

// 执行查询
pool.query('SELECT * FROM users WHERE age > ?', [25], (err, results) => {
  console.log(results);
});

// 使用 Promise
const promisePool = pool.promise();

async function getUsers() {
  const [rows] = await promisePool.query('SELECT * FROM users');
  return rows;
}

异步编程

Node.js 的核心特性是异步非阻塞 I/O。

回调函数

传统异步处理方式:

fs.readFile('file.txt', 'utf8', (err, data) => {
  if (err) {
    console.error(err);
    return;
  }
  console.log(data);
});

Promise

更现代的异步处理方式:

const fs = require('fs').promises;

fs.readFile('file.txt', 'utf8')
  .then(data => console.log(data))
  .catch(err => console.error(err));

async/await

最简洁的异步代码写法:

async function readFile() {
  try {
    const data = await fs.readFile('file.txt', 'utf8');
    console.log(data);
  } catch (err) {
    console.error(err);
  }
}

readFile();

事件发射器

Node.js 的事件驱动架构:

const EventEmitter = require('events');

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter();
myEmitter.on('event', () => {
  console.log('an event occurred!');
});
myEmitter.emit('event');

调试与测试

调试 Node.js 应用

  1. 使用 console.log
  2. 使用 Node.js 内置调试器:
   node inspect app.js
  1. 使用 Chrome DevTools:
   node --inspect app.js

然后在 Chrome 中访问 chrome://inspect

  1. 使用 VS Code 的调试功能

单元测试

使用 Jest 测试框架:

安装 Jest:

npm install --save-dev jest

测试示例:

// sum.js
function sum(a, b) {
  return a + b;
}
module.exports = sum;

// sum.test.js
const sum = require('./sum');

test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3);
});

运行测试:

npx jest

部署与性能优化

部署 Node.js 应用

  1. 传统部署:

    • 安装 Node.js 和 npm
    • 克隆代码仓库
    • npm install
    • npm start (或使用 PM2)
  2. 使用 PM2 进程管理:
   npm install -g pm2
   pm2 start app.js
   pm2 list
   pm2 monit
   pm2 save
   pm2 startup
  1. 容器化部署 (Docker):
   FROM node:14
   WORKDIR /app
   COPY package*.json ./
   RUN npm install
   COPY . .
   EXPOSE 3000
   CMD ["node", "app.js"]

性能优化建议

  1. 使用最新 LTS 版本的 Node.js
  2. 启用集群模式 (cluster 模块)
  3. 优化数据库查询
  4. 使用缓存 (Redis)
  5. 压缩响应数据
  6. 实现负载均衡
  7. 监控应用性能
  8. 使用 gzip 压缩
  9. 减少同步操作
  10. 合理使用流处理大文件

安全最佳实践

  1. 保持依赖项更新
  2. 使用 Helmet 中间件
  3. 验证用户输入
  4. 实现适当的身份验证
  5. 处理错误而不暴露敏感信息
  6. 使用 HTTPS
  7. 设置适当的 CORS 策略
  8. 限制请求大小
  9. 防止暴力破解攻击
  10. 定期进行安全审计

总结

本教程涵盖了 Node.js 从基础到高级的核心概念,包括:

  • Node.js 基本概念和工作原理
  • 模块系统和文件操作
  • HTTP 服务器和 Express 框架
  • 数据库连接
  • 异步编程模式
  • 调试、测试和部署

Node.js 的强大之处在于其丰富的生态系统和高效的 I/O 处理能力。随着不断实践,你将能够构建各种类型的服务器端应用。

要进一步学习,可以探索:

  • WebSocket 和实时应用
  • 微服务架构
  • Serverless 无服务器架构
  • GraphQL API 开发
  • TypeScript 与 Node.js
  • 性能调优和高级模式

Happy coding with Node.js!









results matching ""

    No results matching ""