首页  >  文章  >  web前端  >  如何在 Node.js (Express.js) 中构建后端代码

如何在 Node.js (Express.js) 中构建后端代码

WBOY
WBOY原创
2024-08-16 06:25:02747浏览

How to Structure Your Backend Code in Node.js (Express.js)

使用 Express.js 开发 Node.js 应用程序时,有效构建代码库对于可维护性、可扩展性和易于协作至关重要。组织良好的项目结构使您能够管理复杂性,从而更轻松地导航和理解代码。在本博客中,我们将探索 Express.js 应用程序的典型文件夹结构,并解释每个目录和文件的用途。

项目结构概述
以下是 Express.js 应用程序的常见文件夹结构:

?
├── ? app.js
├── ? bin
├── ? config
├── ? controllers
│   ├── ? customer.js
│   ├── ? product.js
│   └── ...
├── ? middleware
│   ├── ? auth.js
│   ├── ? logger.js
│   └── ...
├── ? models
│   ├── ? customer.js
│   ├── ? product.js
│   └── ...
├── ? routes
│   ├── ? api.js
│   ├── ? auth.js
│   └── ...
├── ? public
│   ├── ? css
│   ├── ? js
│   ├── ? images
│   └── ...
├── ? views
│   ├── ? index.ejs
│   ├── ? product.ejs
│   └── ...
├── ? tests
│   ├── ? unit
│   ├── ? integration
│   ├── ? e2e
│   └── ...
├── ? utils
│   ├── ? validation.js
│   ├── ? helpers.js
│   └── ...
└── ? node_modules

各个目录和文件的说明
应用程序.js
app.js 文件是应用程序的入口点。您可以在其中初始化 Express 应用程序、设置中间件、定义路由并启动服务器。将其视为 Web 应用程序的控制中心。

const express = require('express');
const app = express();
const config = require('./config');
const routes = require('./routes');
// Middleware setup
app.use(express.json());
// Routes setup
app.use('/api', routes);
// Start server
const PORT = config.port || 3000;
app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});
module.exports = app;

bin
bin 目录通常包含用于启动 Web 服务器的脚本。这些脚本可用于设置环境变量或管理不同的环境(例如开发、生产)。

示例:bin/www

#!/usr/bin/env node
const app = require('../app');
const debug = require('debug')('your-app:server');
const http = require('http');
const port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
const server = http.createServer(app);
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
function normalizePort(val) {
  const port = parseInt(val, 10);
  if (isNaN(port)) return val;
  if (port >= 0) return port;
  return false;
}
function onError(error) {
  if (error.syscall !== 'listen') throw error;
  const bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port;
  switch (error.code) {
    case 'EACCES':
      console.error(bind + ' requires elevated privileges');
      process.exit(1);
      break;
    case 'EADDRINUSE':
      console.error(bind + ' is already in use');
      process.exit(1);
      break;
    default:
      throw error;
  }
}
function onListening() {
  const addr = server.address();
  const bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port;
  debug('Listening on ' + bind);
}

配置
config 目录保存应用程序的配置文件,例如数据库连接、服务器设置和环境变量。

示例:config/index.js

module.exports = {
  port: process.env.PORT || 3000,
  db: {
    host: 'localhost',
    port: 27017,
    name: 'mydatabase'
  }
};

控制器
控制器包含处理传入请求和生成响应的逻辑。控制器目录中的每个文件通常对应于应用程序的不同部分(例如客户、产品)。

示例:controllers/customer.js

const Customer = require('../models/customer');
exports.getAllCustomers = async (req, res) => {
  try {
    const customers = await Customer.find();
    res.json(customers);
  } catch (err) {
    res.status(500).json({ message: err.message });
  }
};

中间件
中间件功能用于在请求到达控制器之前对其进行处理。它们可以处理身份验证、日志记录和请求验证等任务。

示例:middleware/auth.js

module.exports = (req, res, next) => {
  const token = req.header('Authorization');
  if (!token) return res.status(401).json({ message: 'Access Denied' });
  try {
    const verified = jwt.verify(token, process.env.JWT_SECRET);
    req.user = verified;
    next();
  } catch (err) {
    res.status(400).json({ message: 'Invalid Token' });
  }
};

模型
模型定义数据的结构并处理与数据库的交互。每个模型文件通常对应于不同的数据实体(例如,客户、产品)。

示例:models/customer.js

const mongoose = require('mongoose');
const customerSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true
  },
  email: {
    type: String,
    required: true,
    unique: true
  },
  createdAt: {
    type: Date,
    default: Date.now
  }
});
module.exports = mongoose.model('Customer', customerSchema);

路线
路由定义了应用程序不同部分的路径,并将它们映射到适当的控制器。

示例:routes/api.js

const express = require('express');
const router = express.Router();
const customerController = require('../controllers/customer');
router.get('/customers', customerController.getAllCustomers);
module.exports = router;

公开
public 目录包含直接向客户端提供服务的静态文件,例如 CSS、JavaScript 和图像。

示例:目录结构

public/
├── css/
├── js/
├── images/

观看次数
视图是为客户端呈现 HTML 的模板。使用 EJS、Pug 或 Handlebars 等模板引擎,您可以生成动态 HTML。

示例:views/index.ejs

<!DOCTYPE html>
<html>
<head>
  <title>My App</title>
  <link rel="stylesheet" href="/css/styles.css">
</head>
<body>
  <h1>Welcome to My App</h1>
  <div id="content">
    <%- content %>
  </div>
</body>
</html>

测试
测试目录包含测试文件,以确保您的应用程序正常工作。测试通常分为单元测试、集成测试和端到端 (e2e) 测试。

示例:目录结构

tests/
├── unit/
├── integration/
├── e2e/

实用程序
实用程序函数和辅助模块存储在 utils 目录中。这些函数执行整个应用程序中使用的常见任务,例如验证和格式化。

示例:utils/validation.js

exports.isEmailValid = (email) => {
  const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  return re.test(String(email).toLowerCase());
};

节点模块
node_modules 目录包含您的项目所需的所有依赖项。该目录由 npm(或yarn)管理,包含从 npm 注册表安装的软件包。

结论
使用 Express.js 的结构良好的 Node.js 应用程序可以增强可维护性、可扩展性和协作性。结构中的每个目录和文件都有特定的用途,从处理配置和定义路由到管理中间件和渲染视图。通过有效地组织代码库,您可以轻松构建强大且可扩展的应用程序。

以上是如何在 Node.js (Express.js) 中构建后端代码的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn