Express.js Secrets That Senior Developers Don’t Share
Express.js 经常被用作在 Node.js 中构建 web 应用程序的首选框架。它轻量、无特定方式的约束、并且非常灵活,因此深受初学者和资深开发者的喜爱。然而,从编写 简单的 Express 应用 到构建 可扩展、易维护且高性能的应用程序,之间存在一定的差距。
资深开发者,尤其是那些有着多年生产环境经验的,掌握了一些不易得的窍门,使他们的Express应用更快、更安全、更易维护。这些经验很少会在教程或官方文档中提及。
1. 巧妙运用中间件:隐藏的性能代价中间件是 Express 的心脏。然而,不当使用中间件 会拖慢你的应用并形成瓶颈。大多数人会犯以下几个错误:
一个常见的错误:使用过多的全局中间件(全局范围的中间件)许多开发者在顶层添加中间件,这会影响到每一个请求,即使在某些情况下并不需要也是如此。
app.use((req, res, next) => {
console.log('收到请求了');
next();
});
app.use(someHeavyMiddleware);
app.get('/simple-route', (req, res) => {
res.send('Hello, world!');
});
在这里,即使是简单的路由,比如 /simple-route
,也必须经过 someHeavyMiddleware
,从而使速度变慢下来。
相反,只需在必要时才添加中间件:
app.get('/simple-route', (req, res) => {
res.send('你好,世界!');
});
app.use('/heavy-api', someHeavyMiddleware);
app.get('/heavy-api/data', (req, res) => {
res.send('这条路由实际上需要一些重型中间件处理');
});
技巧:使用 router.use()
代替 app.use()
与其全局挂载中间件,不如仅将其绑定到相关的路由:
const userRouter = express.Router();
userRouter.use(authMiddleware); // 使用认证中间件
userRouter.get('/profile', (req, res) => {
res.send('用户资料页面');
});
app.use('/user', userRouter);
比如说,现在,authMiddleware
只作用于 /user
路由路径。
处理异步函数里的错误可能会变得一团糟且重复。大多数开发人员会如下编写容易出错的代码:
app.get('/data', async (req, res) => {
try {
data = await fetchData();
res.send(data);
} catch (err) {
res.status(500).send('发生了一些错误');
}
});
遇到什么问题? 每个路由都需要相同的 try/catch
模式化处理,导致臃肿的代码。
用一个辅助函数来封装你的异步路由
const asyncHandler = fn => (req, res, next) => {
// 定义一个处理异步请求的处理器
Promise.resolve(fn(req, res, next)).catch(next);
};
app.get('/data', asyncHandler(async (req, res) => {
// 定义一个处理 /data 路由的方法
let data = await fetchData();
// 从服务器获取数据
res.send(data);
// 将数据发送给客户端
}));
现在,错误会自动传递给 Express 错误处理程序,这样可以保持你的代码整洁且不冗余。
3. 精通 Express 路由:扩展小技巧如果你的 server.js
文件中有 100 多个路由,你就走偏了,。一个资深开发者会告诉你,将路由拆分成模块文件 是非常重要的。
- 创建一个
**/routes**
目录 - 将每个功能分别放到单独的文件中
例如,不要把所有东西都放在 server.js
文件里,而是创建一个清晰的结构。
/文件路由
├── users.js
├── products.js
├── orders.js
在 users.js
文件中:
const express = require('express');
const router = express.Router();
router.get('/profile', (req, res) => {
res.send('用户个人主页');
});
module.exports = router;
在 server.js
文件中:
const express = require('express');
const app = express();
app.use('/users', require('./routes/users'));
app.use('/products', require('./routes/products'));
app.listen(3000, () => console.log('服务器已经在端口3000上运行'));
现在,你的路由是模块化、灵活扩展且维护简单的,并且更符合中文的语境和习惯。
4. 正确使用环境变量的方法许多初级开发者会在他们的代码中直接写入敏感信息(硬编码指直接将敏感信息写入代码中):
这里定义了一个名为 dbPassword 的常量,其值为 'supersecret123'。
哎呀,大错特错! 别在源代码里写秘密哦,千万不要!
正确使用.env
:资深开发者的技巧
- 安装一下
dotenv
。
运行此命令来安装dotenv模块:
npm install dotenv
- 创建一个
.env
文件。
数据库密码设置为supersecret123
- 在你的应用中用它,
// 加载环境变量配置
require('dotenv').config();
const 数据库密码 = process.env.DB_PASSWORD;
现在,你的凭证变得既安全又方便修改。
5.res.locals
小技巧:减少不必要的数据库查询
许多开发人员在每次请求时都去取用户数据,从而拖慢了性能。
app.use(async (req, res, next) => {
// 获取用户信息
const user = await fetchUser(req.userId);
// 将用户信息附加到请求对象中
req.user = user;
// 继续处理下一个中间件
next();
});
高级开发技巧:将数据存储在 res.locals
使用 res.locals
来存储特定请求的数据,从而避免使 req
臃肿:
app.use(async (req, res, next) => {
res.locals.user = await fetchUser(req.userId); // 获取用户信息
next();
});
app.get('/dashboard', (req, res) => {
res.send(`欢迎你,${res.locals.user.name}`); // 欢迎用户到仪表盘页面
});
这样可以让 req
保持 轻量,同时也能让你的中间件 更加高效。
next('route')
技巧:
有时候,你想跳过当前中间件并直接进入下一个路由处理程序。大多数开发者都不知道next('route')
这个功能的存在!
app.get('/admin', checkAuth, (req, res, next) => {
if (!req.user.isAdmin) return next('route'); // 跳过此中间件
res.send('你好,管理员!');
});
app.get('/admin', (req, res) => {
res.send('你不是管理员'); // 返回非管理员信息
});
非管理员用户现在跳过了第一个处理步骤,而是会收到一条友好的消息。
最后的感想:像有经验的开发者那样用 Express 编程Express 是个简单易学但难精通的框架。通过运用这些技巧,你将能够编写出这样的应用程序:
更快 — 通过减少不必要的中间件和优化路由处理
更简洁 — 使用模块化路由和异步错误处理
更安全 — 通过使用 .env
避免泄露秘密
更易维护 — 通过保持请求特定数据轻量化
资深开发者和初级开发者之间的主要差别不在于是否了解框架,而是如何聪明地使用框架。
也许您也会喜欢:
7 个提升 API 性能的技巧 - Arunangshu Das 博客。点击此处阅读 https://blog.arunangshudas.com/7-tips-for-boosting-your-api-performance/
3), 如何识别后端瓶颈
4) 8个用于开发可扩展后端解决方案的实用工具(https://blog.arunangshudas.com/8-tools-for-developing-scalable-backend-solutions/)
- 6个后端架构设计中的常见的错误:6 Common Mistakes in Backend Architecture Design
7 个可扩展后端架构的实用建议 https://blog.arunangshudas.com/7-essential-tips-for-scalable-backend-architecture/
8) JWT 和 Paseto:如何为现代应用程序选择基于令牌的认证
9) Node.js 中的高流量 API 请求速率限制和防止滥用策略
10) 你能回答这个问题吗?这是一个高级JavaScript Promise面试问题。
11), 五个原因 JWT 可能不是最佳选择
13) 在 package.json 配置中的 7 个常见错误。
更多博客请看这里
在评论区分享你的经历,咱们来聊聊如何解决这些问题!
关注我领英
共同学习,写下你的评论
评论加载中...
作者其他优质文章