You need to enable JavaScript to run this app. 不使用框架的简单Node.js应用应采用怎样的项目结构?
优惠活动
大模型
产品
解决方案
定价
更多

不使用框架的简单Node.js应用应采用怎样的项目结构?

无第三方框架极简API项目结构方案

仅需安装dotenv和你所用数据库对应的驱动包(比如mysql2、pg等),无其他任何重型框架依赖,完全适配你所说的仅支持基础API请求、数据库读写的极简脚本场景。


最终项目结构

your-project/
├── index.js          # 项目入口
├── config.js         # 全局配置
├── route-handler.js  # API路由匹配与请求处理
├── db/
│   ├── index.js      # 数据库连接初始化
│   └── crud.js       # 通用数据库增删改查封装
├── utils/
│   └── request.js    # 请求参数解析、响应格式化工具
└── .env              # 敏感环境变量

各文件职责说明

  • index.js:项目启动入口,仅做三件事:加载配置、初始化数据库连接、启动原生http服务监听端口,示例代码:
const http = require('http')
const { PORT } = require('./config')
const { initDb } = require('./db')
const routeHandler = require('./route-handler')

initDb().then(() => {
  http.createServer(routeHandler).listen(PORT, () => console.log(`服务启动在端口${PORT}`))
})
  • config.js:统一管理所有固定配置,引用.env的敏感变量,避免硬编码散落在各个文件:
require('dotenv').config()
module.exports = {
  PORT: process.env.PORT || 3000,
  DB_CONFIG: {
    host: process.env.DB_HOST,
    user: process.env.DB_USER,
    password: process.env.DB_PWD,
    database: process.env.DB_NAME
  }
}
  • route-handler.js:所有API路由的匹配逻辑,用原生判断即可不需要引入路由框架:
const { parseReq, sendRes } = require('./utils/request')
const { addData, queryData } = require('./db/crud')

module.exports = async (req, res) => {
  const { method, path, body } = await parseReq(req)
  // 路由匹配,新增接口直接在这里加规则即可
  if (method === 'GET' && path === '/api/query') return sendRes(res, 200, await queryData(body.id))
  if (method === 'POST' && path === '/api/add') return sendRes(res, 200, await addData(body))
  return sendRes(res, 404, { msg: '接口不存在' })
}
  • db/index.js:仅封装数据库连接、断开逻辑,不要和业务CRUD逻辑混写:
const mysql = require('mysql2/promise')
const { DB_CONFIG } = require('../config')
let pool
async function initDb() {
  pool = mysql.createPool(DB_CONFIG)
  await pool.getConnection()
  console.log('数据库连接成功')
}
module.exports = { initDb, pool }
  • db/crud.js:所有和数据库读写相关的业务逻辑都放在这里,上层不需要直接操作数据库连接:
const { pool } = require('./index')
async function queryData(id) {
  const [rows] = await pool.query('SELECT * FROM test_table WHERE id = ?', [id])
  return rows[0]
}
async function addData(data) {
  const [res] = await pool.query('INSERT INTO test_table SET ?', [data])
  return { insertId: res.insertId }
}
module.exports = { queryData, addData }
  • utils/request.js:统一处理请求参数解析、响应格式化,避免每个接口重复写header、解析body的代码:
function parseReq(req) {
  return new Promise(resolve => {
    let body = ''
    req.on('data', chunk => body += chunk.toString())
    req.on('end', () => resolve({
      method: req.method,
      path: req.url.split('?')[0],
      body: body ? JSON.parse(body) : {}
    }))
  })
}
function sendRes(res, code, data) {
  res.setHeader('Content-Type', 'application/json')
  res.writeHead(code)
  res.end(JSON.stringify(data))
}
module.exports = { parseReq, sendRes }
  • .env:存放所有敏感信息,不要提交到代码仓库,示例:
PORT=3000
DB_HOST=127.0.0.1
DB_USER=root
DB_PWD=123456
DB_NAME=test_db

后续扩展规则

严格遵循以下规则即可避免后续开发结构混乱:

  • 新增接口直接在route-handler.js加路由匹配规则
  • 新增数据库操作直接在db/crud.js加对应方法
  • 新增通用工具函数都放在utils目录下
  • 所有配置都统一放在config.js和.env

内容的提问来源于stack exchange,提问作者aaron

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 12:12:01