摘要

Node.js 凭借其非阻塞I/O和事件驱动的特性,在后端开发领域占据了重要地位。本文将深入探讨Node.js的核心概念、常用模块、Web框架、数据库交互、测试以及性能优化,旨在为开发者提供一份全面的Node.js技术指南。

一、Node.js基础

(一)事件循环 (Event Loop)

Node.js 的核心是事件循环,它使得Node.js可以在单线程中处理大量并发连接,而不会造成阻塞。

1
2
3
4
5
6
7
8
9
10
11
12
13
console.log('start');

setTimeout(() => {
console.log('setTimeout');
}, 0);

Promise.resolve().then(() => {
console.log('Promise');
});

console.log('end');

// 输出顺序: start, end, Promise, setTimeout

(二)异步I/O

Node.js的所有I/O操作(如文件读写、网络请求)都是异步的,这极大地提升了应用的性能。

1
2
3
4
5
6
7
8
9
10
11
const fs = require('fs');

// 异步读取文件
fs.readFile('/path/to/file', 'utf8', (err, data) => {
if (err) throw err;
console.log(data);
});

// 同步读取文件 (会阻塞事件循环)
const data = fs.readFileSync('/path/to/file', 'utf8');
console.log(data);

二、核心模块

(一)fs (文件系统)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const fs = require('fs');
const path = require('path');

const filePath = path.join(__dirname, 'example.txt');

// 写入文件
fs.writeFile(filePath, 'Hello Node.js', (err) => {
if (err) throw err;
console.log('File written successfully');
});

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

(二)http (HTTP服务器)

1
2
3
4
5
6
7
8
9
10
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, '127.0.0.1', () => {
console.log('Server running at http://127.0.0.1:3000/');
});

(三)path (路径处理)

1
2
3
4
5
6
7
8
const path = require('path');

const myPath = '/foo/bar/baz/asdf/quux.html';

console.log(path.dirname(myPath)); // /foo/bar/baz/asdf
console.log(path.basename(myPath)); // quux.html
console.log(path.extname(myPath)); // .html
console.log(path.join('/foo', 'bar', 'baz/asdf', 'quux', '..')); // /foo/bar/baz/asdf

三、包管理器 (npm & yarn)

Node.js拥有庞大的生态系统,npm是其默认的包管理器。

1
2
3
4
5
6
7
8
9
10
11
12
# 初始化项目
npm init -y

# 安装依赖
npm install express

# 安装开发依赖
npm install --save-dev nodemon

# 运行脚本
# package.json -> "scripts": { "start": "node index.js" }
npm start

四、Web开发框架

(一)Express.js

Express是目前最流行的Node.js Web框架,以其简洁、灵活的API著称。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
const express = require('express');
const app = express();
const port = 3000;

// 中间件
app.use(express.json());
app.use((req, res, next) => {
console.log(`${req.method} ${req.url}`);
next();
});

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

app.post('/users', (req, res) => {
const user = req.body;
res.status(201).send(user);
});

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

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

(二)Koa.js

Koa由Express原班人马打造,利用async/await提供了更优雅的异步处理方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
const Koa = require('koa');
const Router = require('koa-router');
const bodyParser = require('koa-bodyparser');

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

// 中间件
app.use(bodyParser());
app.use(async (ctx, next) => {
console.log(`Processing ${ctx.method} ${ctx.url}...`);
await next();
});

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

router.post('/users', (ctx) => {
const user = ctx.request.body;
ctx.status = 201;
ctx.body = user;
});

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

app.listen(3000, () => {
console.log('Koa app listening on port 3000');
});

五、数据库交互

(一)MongoDB (使用 Mongoose)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const mongoose = require('mongoose');

mongoose.connect('mongodb://localhost/mydatabase');

const userSchema = new mongoose.Schema({
name: String,
email: { type: String, required: true, unique: true },
age: Number
});

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

async function createUser() {
const user = new User({ name: 'Alice', email: 'alice@example.com', age: 30 });
await user.save();
console.log('User created');
}

createUser();

(二)MySQL (使用 Sequelize)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const { Sequelize, DataTypes } = require('sequelize');

const sequelize = new Sequelize('database', 'username', 'password', {
host: 'localhost',
dialect: 'mysql'
});

const User = sequelize.define('User', {
name: {
type: DataTypes.STRING,
allowNull: false
},
email: {
type: DataTypes.STRING,
allowNull: false,
unique: true
}
});

async function syncAndCreate() {
await sequelize.sync({ force: true });
const user = await User.create({ name: 'Bob', email: 'bob@example.com' });
console.log('User created:', user.toJSON());
}

syncAndCreate();

六、测试

(一)Jest

1
2
3
4
5
6
7
8
9
10
11
12
// 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);
});

(二)Supertest (用于API测试)

1
2
3
4
5
6
7
8
9
10
11
const request = require('supertest');
const app = require('./app'); // 你的Express应用

describe('GET /', () => {
it('responds with Hello Express!', (done) => {
request(app)
.get('/')
.expect('Content-Type', /text/)
.expect(200, 'Hello Express!', done);
});
});

七、性能优化与最佳实践

  • 使用集群 (Cluster) 模块: 利用多核CPU能力。
  • 管理内存: 避免内存泄漏,使用工具如heapdump进行分析。
  • 使用流 (Streams): 高效处理大数据。
  • 代码可维护性: 遵循模块化、单一职责原则。
  • 错误处理: 实现健壮的错误处理机制。
  • 使用环境变量: 管理不同环境的配置。

八、总结

Node.js 是一个功能强大且用途广泛的平台,适用于构建高性能的网络应用、API服务、微服务等。通过掌握其核心概念和生态系统,开发者可以构建出高效、可扩展的后端服务。

九、参考资料