持续学习路径:Node.js 编程课程

1. Node.js 简介和特性

理论解释

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时环境,允许开发者使用 JavaScript 编写服务器端应用程序。Node.js 的非阻塞 I/O 模型使其非常适合构建高性能、可扩展的网络应用。

代码示例

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

实践练习

  1. 安装 Node.js 并运行上述代码。
  2. 尝试编写一个简单的 HTTP 服务器。

2. 环境搭建和版本管理(nvm)

理论解释

Node Version Manager (nvm) 是一个用于管理多个 Node.js 版本的工具。它允许你在同一台机器上轻松切换不同的 Node.js 版本。

代码示例

nvm install 14.17.0
nvm use 14.17.0

实践练习

  1. 安装 nvm 并使用它来安装和切换 Node.js 版本。
  2. 创建一个项目文件夹,并在其中使用特定版本的 Node.js。

3. 创建第一个 Node.js 应用

理论解释

创建一个简单的 Node.js 应用程序,包括基本的文件结构和代码组织。

代码示例

const http = require('http');

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('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/');
});

实践练习

  1. 创建一个简单的 HTTP 服务器,返回 "Hello, World!"。
  2. 尝试修改服务器以返回不同的内容。

4. 模块系统(CommonJS 和 ES Modules)

理论解释

Node.js 支持两种模块系统:CommonJS 和 ES Modules。CommonJS 是 Node.js 的默认模块系统,而 ES Modules 是 ECMAScript 标准的一部分。

代码示例

CommonJS

// math.js
module.exports = {
  add: (a, b) => a + b
};

// index.js
const math = require('./math');
console.log(math.add(1, 2)); // 输出: 3

ES Modules

// math.js
export const add = (a, b) => a + b;

// index.js
import { add } from './math.js';
console.log(add(1, 2)); // 输出: 3

实践练习

  1. 创建一个 CommonJS 模块并使用它。
  2. 创建一个 ES Modules 模块并使用它。

5. 包管理器(npm 和 yarn)

理论解释

npm 和 yarn 是 Node.js 的包管理器,用于安装、管理和发布 JavaScript 包。

代码示例

npm install express
yarn add express

实践练习

  1. 使用 npm 安装一个包(如 express)。
  2. 使用 yarn 安装同一个包,并比较两者的速度。

6. 事件循环和异步编程

理论解释

Node.js 的事件循环是其非阻塞 I/O 模型的核心。异步编程允许你在等待 I/O 操作完成时执行其他任务。

代码示例

setTimeout(() => {
  console.log('This will run after 1 second');
}, 1000);

console.log('This will run first');

实践练习

  1. 编写一个异步函数,使用 setTimeout 模拟延迟。
  2. 尝试使用 Promise 和 async/await 重写上述代码。

7. 回调函数、Promise 和 async/await

理论解释

回调函数、Promise 和 async/await 是处理异步操作的不同方式。

代码示例

回调函数

function fetchData(callback) {
  setTimeout(() => {
    callback('Data fetched');
  }, 1000);
}

fetchData((data) => {
  console.log(data);
});

Promise

function fetchData() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve('Data fetched');
    }, 1000);
  });
}

fetchData().then((data) => {
  console.log(data);
});

async/await

async function fetchData() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve('Data fetched');
    }, 1000);
  });
}

(async () => {
  const data = await fetchData();
  console.log(data);
})();

实践练习

  1. 使用回调函数编写一个异步操作。
  2. 使用 Promise 和 async/await 重写上述代码。

8. 流(Streams)和缓冲区(Buffers)

理论解释

流和缓冲区是处理大量数据的高效方式。流允许你逐步处理数据,而缓冲区是存储数据的临时空间。

代码示例

const fs = require('fs');

const readStream = fs.createReadStream('input.txt');
const writeStream = fs.createWriteStream('output.txt');

readStream.on('data', (chunk) => {
  writeStream.write(chunk);
});

readStream.on('end', () => {
  writeStream.end();
});

实践练习

  1. 创建一个读取文件并将其内容写入另一个文件的流。
  2. 尝试使用缓冲区处理二进制数据。

9. 文件系统操作

理论解释

Node.js 提供了丰富的文件系统操作 API,允许你读取、写入、删除和操作文件。

代码示例

const fs = require('fs');

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

实践练习

  1. 读取一个文件并将其内容输出到控制台。
  2. 写入一个新文件并验证其内容。

10. 网络编程(HTTP/HTTPS 模块)

理论解释

Node.js 提供了内置的 http 和 https 模块,用于创建 HTTP 和 HTTPS 服务器。

代码示例

const http = require('http');

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('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/');
});

实践练习

  1. 创建一个简单的 HTTP 服务器。
  2. 尝试使用 https 模块创建一个 HTTPS 服务器。

11. Express.js 框架入门

理论解释

Express.js 是一个流行的 Node.js 框架,用于构建 Web 应用程序和 API。

代码示例

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

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

app.listen(3000, () => {
  console.log('Server running at http://localhost:3000/');
});

实践练习

  1. 安装 Express.js 并创建一个简单的 Web 应用程序。
  2. 尝试添加更多的路由和处理程序。

12. 路由和中间件

理论解释

路由是定义如何响应客户端请求的过程。中间件是处理请求和响应的函数。

代码示例

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

app.use((req, res, next) => {
  console.log('Middleware executed');
  next();
});

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

app.listen(3000, () => {
  console.log('Server running at http://localhost:3000/');
});

实践练习

  1. 创建一个 Express 应用程序并添加中间件。
  2. 尝试定义多个路由和中间件。

13. 模板引擎(EJS, Pug)

理论解释

模板引擎允许你在服务器端生成动态 HTML 内容。EJS 和 Pug 是两种流行的模板引擎。

代码示例

EJS

app.set('view engine', 'ejs');

app.get('/', (req, res) => {
  res.render('index', { title: 'My App' });
});

Pug

app.set('view engine', 'pug');

app.get('/', (req, res) => {
  res.render('index', { title: 'My App' });
});

实践练习

  1. 使用 EJS 创建一个动态页面。
  2. 使用 Pug 创建一个类似的页面。

14. RESTful API 设计和实现

理论解释

RESTful API 是一种基于 HTTP 协议的 API 设计风格,使用标准的 HTTP 方法(如 GET、POST、PUT、DELETE)来操作资源。

代码示例

app.get('/api/users', (req, res) => {
  res.json([{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }]);
});

app.post('/api/users', (req, res) => {
  res.status(201).json({ id: 3, name: 'Charlie' });
});

实践练习

  1. 创建一个简单的 RESTful API。
  2. 尝试添加更多的资源和操作。

15. 身份认证和授权

理论解释

身份认证是验证用户身份的过程,而授权是确定用户是否有权访问特定资源的过程。

代码示例

const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;

passport.use(new LocalStrategy((username, password, done) => {
  // 验证逻辑
}));

app.post('/login', passport.authenticate('local', { successRedirect: '/', failureRedirect: '/login' }));

实践练习

  1. 使用 Passport.js 实现本地身份认证。
  2. 尝试添加授权逻辑。

16. SQL 数据库(MySQL, PostgreSQL)

理论解释

SQL 数据库是关系型数据库,使用结构化查询语言(SQL)进行数据操作。

代码示例

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

connection.query('SELECT * FROM users', (err, results) => {
  if (err) throw err;
  console.log(results);
});

实践练习

  1. 连接到 MySQL 数据库并执行查询。
  2. 尝试使用 PostgreSQL 数据库。

17. NoSQL 数据库(MongoDB)

理论解释

NoSQL 数据库是非关系型数据库,通常用于存储非结构化或半结构化数据。

代码示例

const MongoClient = require('mongodb').MongoClient;
const uri = 'mongodb://localhost:27017';
const client = new MongoClient(uri, { useNewUrlParser: true });

client.connect(err => {
  const collection = client.db("test").collection("users");
  collection.find({}).toArray((err, docs) => {
    if (err) throw err;
    console.log(docs);
    client.close();
  });
});

实践练习

  1. 连接到 MongoDB 数据库并执行查询。
  2. 尝试插入和更新数据。

18. ORM 和 ODM(Sequelize, Mongoose)

理论解释

ORM(对象关系映射)和 ODM(对象文档映射)是用于在数据库和应用程序之间进行数据映射的工具。

代码示例

Sequelize

const { Sequelize, DataTypes } = require('sequelize');
const sequelize = new Sequelize('sqlite::memory:');

const User = sequelize.define('User', {
  name: DataTypes.STRING
});

sequelize.sync().then(() => {
  return User.create({ name: 'John' });
}).then(user => {
  console.log(user.toJSON());
});

Mongoose

const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/test', { useNewUrlParser: true });

const userSchema = new mongoose.Schema({ name: String });
const User = mongoose.model('User', userSchema);

const user = new User({ name: 'John' });
user.save().then(() => console.log('User saved'));

实践练习

  1. 使用 Sequelize 创建一个模型并执行 CRUD 操作。
  2. 使用 Mongoose 创建一个模型并执行类似的操作。

19. 数据库迁移和种子数据

理论解释

数据库迁移是管理数据库模式更改的过程。种子数据是用于填充数据库的初始数据。

代码示例

Sequelize

const { Sequelize } = require('sequelize');
const sequelize = new Sequelize('sqlite::memory:');

const User = sequelize.define('User', { name: DataTypes.STRING });

sequelize.sync({ force: true }).then(() => {
  return User.bulkCreate([{ name: 'John' }, { name: 'Jane' }]);
}).then(() => {
  return User.findAll();
}).then(users => {
  console.log(users);
});

实践练习

  1. 使用 Sequelize 创建一个迁移文件并执行迁移。
  2. 使用 Sequelize 创建种子数据并填充数据库。

20. 进程和子进程

理论解释

Node.js 允许你创建和管理进程和子进程,以便在同一台机器上运行多个任务。

代码示例

const { spawn } = require('child_process');
const ls = spawn('ls', ['-lh', '/usr']);

ls.stdout.on('data', (data) => {
  console.log(`stdout: ${data}`);
});

ls.stderr.on('data', (data) => {
  console.error(`stderr: ${data}`);
});

ls.on('close', (code) => {
  console.log(`child process exited with code ${code}`);
});

实践练习

  1. 创建一个子进程并执行一个外部命令。
  2. 尝试捕获子进程的输出和错误。

21. 集群和负载均衡

理论解释

集群允许你在多个 Node.js 进程之间分配负载,以提高应用程序的性能和可靠性。

代码示例

const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  cluster.on('exit', (worker, code, signal) => {
    console.log(`worker ${worker.process.pid} died`);
  });
} else {
  http.createServer((req, res) => {
    res.writeHead(200);
    res.end('hello world\n');
  }).listen(8000);

  console.log(`Worker ${process.pid} started`);
}

实践练习

  1. 创建一个集群并启动多个工作进程。
  2. 尝试在集群中处理多个请求。

22. WebSocket 实时通信

理论