第3章:Node.js环境搭建:Express框架快速上手、项目结构设计、环境变量配置(dotenv)、数据库选型(MongoDB/MySQL)
好,咱们正式开始动手了。
这一章,我会带你从零搭一个Node.js后端项目。说白了,就是把你脑子里的「认证授权」想法,变成能跑起来的代码。
我个人习惯,先搭好架子再写业务。架子稳了,后面写代码才不慌。
3.1 Express框架快速上手
Express是Node.js最经典的Web框架。我当年刚学Node时,第一个项目就是用Express写的。到现在,它依然是我做中小型项目的首选。
安装很简单,一行命令:
npm init -y
npm install express
然后创建一个 app.js:
const express = require('express');
const app = express();
const port = 3000;
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
跑起来试试:
node app.js
打开浏览器,看到「Hello World!」就对了。
小提示:我建议你用
nodemon 来启动项目。这样改完代码自动重启,不用手动停再起。安装命令:npm install -g nodemon,然后 nodemon app.js。
3.2 项目结构设计
很多新手喜欢把所有代码塞进一个 app.js。嗯,我刚开始也这么干过。结果项目一复杂,找段代码得翻半天。
后来我总结了一套结构,用了好几年,分享给你:
my-auth-app/
├── src/
│ ├── config/ # 配置文件
│ │ └── index.js
│ ├── controllers/ # 控制器(处理请求逻辑)
│ │ └── authController.js
│ ├── models/ # 数据模型
│ │ └── User.js
│ ├── routes/ # 路由定义
│ │ └── authRoutes.js
│ ├── middleware/ # 中间件
│ │ └── authMiddleware.js
│ ├── utils/ # 工具函数
│ │ └── helpers.js
│ └── app.js # 入口文件
├── .env # 环境变量
├── .gitignore
├── package.json
└── README.md
为什么这么分?
- config:放数据库连接、JWT密钥等配置。改配置只动这一个文件夹。
- controllers:处理请求和响应。业务逻辑放这里。
- models:定义数据表结构。MongoDB用Mongoose,MySQL用Sequelize。
- routes:定义API路径。比如
/api/login、/api/register。 - middleware:放认证、日志等中间件。后面讲JWT时会重点用。
核心原则:每个文件只做一件事。一个控制器只处理一类资源,一个模型只对应一个数据表。这样后期维护,你改一个功能不会影响到其他地方。
3.3 环境变量配置(dotenv)
你想想看,数据库密码、JWT密钥这些敏感信息,能直接写在代码里吗?
绝对不能。我见过有人把代码传到GitHub,结果数据库被拖库的惨案。
解决方案就是用环境变量。Node.js里最常用的工具是 dotenv。
安装:
npm install dotenv
在项目根目录创建 .env 文件:
PORT=3000
DB_HOST=localhost
DB_PORT=27017
DB_NAME=my_auth_db
JWT_SECRET=my_super_secret_key_2024
JWT_EXPIRES_IN=7d
然后在 app.js 最顶部引入:
require('dotenv').config();
const port = process.env.PORT || 3000;
const jwtSecret = process.env.JWT_SECRET;
注意:千万不要把
.env 文件提交到Git仓库!记得在 .gitignore 里加上 .env。我曾经有个同事,不小心把生产环境的数据库密码传到了GitHub,结果被爬虫抓到了,数据库被删光勒索。嗯,从那以后我每次提交前都会检查一遍 .gitignore。
另外,我习惯创建一个 src/config/index.js 来统一管理配置:
require('dotenv').config();
module.exports = {
port: process.env.PORT || 3000,
db: {
host: process.env.DB_HOST,
port: process.env.DB_PORT,
name: process.env.DB_NAME,
},
jwt: {
secret: process.env.JWT_SECRET,
expiresIn: process.env.JWT_EXPIRES_IN || '7d',
},
};
这样其他地方引用配置时,只需要 const config = require('./config'); 就行了。清爽。
3.4 数据库选型:MongoDB vs MySQL
这是个大问题。选错了数据库,后面改起来很痛苦。我两个都用过,说说我的感受。
| 对比维度 | MongoDB | MySQL |
|---|---|---|
| 数据模型 | 文档型(JSON-like) | 关系型(表结构) |
| Schema灵活性 | 高,字段可动态变化 | 低,需提前定义表结构 |
| 关联查询 | 弱,需手动处理 | 强,支持JOIN |
| 扩展性 | 天生支持水平扩展 | 垂直扩展为主,分库分表复杂 |
| 学习曲线 | 平缓,JSON思维 | 中等,需理解范式化 |
| 适合场景 | 快速原型、日志、用户资料 | 金融、电商、强一致性业务 |
我个人建议:
- 做认证授权系统,选MongoDB。 为什么呢?用户数据通常是文档结构,比如一个用户有多个角色、多个权限列表。用MongoDB存,一个文档搞定,不用拆成三张表再JOIN回来。
- 如果业务涉及金钱、订单、库存,选MySQL。 这些场景对数据一致性要求极高,关系型数据库的ACID特性是刚需。
我的经验:本课程我会用MongoDB + Mongoose来演示。因为JWT认证的场景,MongoDB用起来最顺手。但如果你公司用的是MySQL,也别慌——认证逻辑是一样的,只是换了个数据库驱动而已。
安装MongoDB和Mongoose:
npm install mongoose
连接数据库的代码,放在 src/config/index.js 里:
const mongoose = require('mongoose');
const connectDB = async () => {
try {
await mongoose.connect(`mongodb://${config.db.host}:${config.db.port}/${config.db.name}`);
console.log('MongoDB connected successfully');
} catch (error) {
console.error('MongoDB connection failed:', error.message);
process.exit(1);
}
};
module.exports = connectDB;
然后在 app.js 里调用:
const connectDB = require('./src/config');
connectDB();
好了,环境搭好了。下一章我们开始写用户注册和登录的接口。到时候你会看到,前面这些准备工作有多重要。
嗯,先到这。去把项目跑起来,有问题随时翻回来看看。