Node.js工程师养成计划
核心代码,注释必读
// download:
3w ukoou com
Node.js是一种开源的服务器端运行环境,利用它可以快速构建高性能、可扩展的网络应用程序。Node.js基于Chrome的V8引擎,允许JavaScript在服务器端运行,并且拥有很多优秀的特性,例如非阻塞I/O和事件驱动等。
下面我们来写一个简单的Node.js服务端项目,实现用户注册、登录和注销的功能。
- 初始化项目 对于Node.js项目,最先需要做的事情就是初始化项目,使用npm init命令生成一个package.json文件。
npm init
- 安装依赖 我们需要安装一些依赖,用来处理HTTP请求、密码加密、处理token等。
npm i express bcrypt jsonwebtoken mongoose cors
- 编写代码 我们创建一个index.js文件作为项目的入口文件,首先引入相关的模块和中间件,配置数据库、前端跨域方案,以及路由控制等。
const express = require("express");
const mongoose = require("mongoose"); //引入mongoose对象
const bcrypt = require("bcrypt"); //引入bcrypt对象,用于密码加密
const jwt = require("jsonwebtoken"); //引入jsonwebtoken对象,用于生成token
const cors = require("cors"); //引入cors对象,用于跨域
const app = express();
const port = 5000;
const dbURL = "mongodb://localhost:27017/node-auth";
app.use(express.json()); //解析json格式的请求体
app.use(cors()); //开启跨域
mongoose //连接数据库
.connect(dbURL, { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => console.log("MongoDB connected..."))
.catch((err) => console.log(err));
//定义用户模型
const Schema = mongoose.Schema;
const userSchema = new Schema({
username: { type: String, required: true },
password: { type: String, required: true },
});
const User = mongoose.model("User", userSchema);
//定义路由
app.post("/signup", (req, res) => {
const { username, password } = req.body;
bcrypt.hash(password, 10, (err, hash) => { //密码加密
if (err) {
res.status(500).json({ error: err });
} else {
User.create({ username: username, password: hash }) //向数据库中插入新用户信息
.then(() => {
res.status(201).json({ message: "User created successfully" });
})
.catch((err) => {
res.status(500).json({ error: err });
});
}
});
});
app.post("/login", (req, res) => {
const { username, password } = req.body;
User.findOne({ username: username }) //在数据库查找用户信息
.then((user) => {
if (user) {
bcrypt.compare(password, user.password, (err, result) => { //密码验证
if (err) {
res.status(401).json({ message: "Authentication failed" });
}
if (result) {
const token = jwt.sign( //生成token
{ username: user.username },
"secret_key",
{ expiresIn: "1h" }
);
res.status(200).json({ message: "Authentication successful", token: token });
}
});
} else {
res.status(401).json({ message: "Authentication failed" });
}
})
.catch((err) => {
res.status(500).json({ error: err });
});
});
app.delete("/logout", (req, res) => {
res.status(200).json({ message: "Logout successful" });
});
app.listen(port, () => {
console.log(`Server started on port ${port}`);
});
- 测试 我们可以使用Postman等工具模拟POST、DELETE请求并检查返回结果,以检查实现是否正确。
Node.js工程师养成计划 Express框架
Express是目前Node.js生态系统内最流行的web框架之一,它提供了一种快速开发高质量web应用的方法。在实际项目中,我们会遇到代码结构混乱、维护难度大等问题,这时需要考虑对项目进行重构。以下是一个简单的Express框架重构项目教程。
-
准备工作 在进行重构前,我们需要对项目进行分析和排查,确定需要改进的部分。确认需要改进的部分后,创建一个branch用于进行重构,保证原有代码的稳定性。
-
结构优化 第一步是对项目的代码结构进行优化。通常情况下,我们在实际开发中会遇到这样一些问题:
- 相关的代码分散在不同的文件中,不方便维护;
- 路由和中间件的管理混乱,没有明确的组织结构;
- 部分功能实现不够模块化,代码冗余。
我们可以通过以下方式优化代码结构:
- 创建一个routes文件夹,用于存放所有路由相关的代码;
- 创建一个middlewares文件夹,用于存放中间件;
- 根据功能将相应的代码进行拆分,组织起来。
下面是一个目录结构示例:
├── config
│ ├── config.js
│ └── db.js
├── controllers
│ ├── auth.js
│ └── user.js
├── middlewares
│ ├── auth.js
│ ├── errorHandler.js
│ └── validator.js
├── models
│ ├── user.js
│ └── ...
├── routes
│ ├── auth.js
│ ├── user.js
│ └── ...
├── utils
│ └── ...
├── app.js
└── package.json
- 优化中间件 第二步是优化中间件,主要有以下几个方面:
- 将所有中间件按照功能分组;
- 将适用于所有路由的中间件提取出来;
- 利用Node.js的异步特性,将中间件封装成promise形式,方便异步调用。
下面是一个中间件示例:
//middlewares/auth.js
const jwt = require("jsonwebtoken");
const { SECRET } = require("../config/config");
exports.verifyToken = (req, res, next) => {
const token = req.headers["x-access-token"];
if (!token) {
return res.status(401).json({ message: "No token provided!" });
}
jwt.verify(token, SECRET, (err, decoded) => {
if (err) {
return res.status(401).json({ message: "Unauthorized!" });
}
req.userId = decoded.id;
next();
});
};
//通过promisify封装中间件
const { promisify } = require("util");
exports.verifyTokenAsync = promisify(exports.verifyToken);
- 优化路由 第三步是对路由进行优化。我们可以通过以下方式来优化路由:
- 将路由分散到不同的文件中;
- 使用路由前缀来提高可读性;
- 把相似的路由组成子路由;
- 引入路由级中间件进行处理。
下面是一个路由示例:
//routes/user.js
const router = require("express").Router();
const userController = require("../controllers/user");
const authMiddleware = require("../middlewares/auth");
router.get("/", userController.getAllUsers);
router.post("/", userController.createUser);
router.use("/:userId", authMiddleware.verifyToken);
router
.route("/:userId")
.get(userController.getUserById)
.put(userController.updateUser)
.delete(userController.deleteUser);
module.exports = router;
-
测试 在所有优化完成后,我们需要进行测试,保证所有功能都能正常工作。在此之前,需要额外关注功能是否存在破坏性的变化,确保新代码和模块对旧代码和模块的引用不会造成问题。
-
整合和发布 重构完成后,我们需要把所有代码整合到一个新版本的分支中,并发布项目。此时应该已经有一个较为清晰的项目结构,所有的路由、中间件、控制器都能明确地归属到特定的文件夹下,减少了对代码的无效搜索和浪费。自此,Express项目的重构就完成了。