MERN全栈开发实战:从Node.js到React整合指南
1. IT自学第二十七天:我的全栈开发进阶之路
作为一名从零开始自学IT的转行者,第二十七天标志着我正式进入全栈开发的实战阶段。这个阶段不再只是看视频和做练习题,而是开始搭建完整的项目框架,将前后端知识串联起来。今天主要攻克了Node.js Express框架与React的整合,以及MongoDB的基础CRUD操作。
关键提示:自学IT最重要的是建立可验证的学习成果,每天至少要完成一个能运行的小demo。
1.1 今日技术栈选择
我选择了MERN技术栈(MongoDB+Express+React+Node.js),这是目前市场上最受欢迎的全栈组合之一。选择这个组合主要基于几个考虑:
- 统一的JavaScript语言环境,避免多语言切换的学习成本
- 丰富的社区资源和现成解决方案
- 就业市场需求量大
具体版本:
- Node.js 18.x LTS版本(长期支持版更稳定)
- Express 4.x(避免直接用最新的5.x,文档还不完善)
- React 18.x(支持最新的并发渲染特性)
- MongoDB 6.x(社区版足够学习使用)
2. 开发环境搭建实录
2.1 前端工程初始化
使用Vite创建React项目比传统create-react-app快很多:
npm create vite@latest my-app --template react cd my-app npm install特别注意的点:
- 一定要加
--template react明确指定模板 - 安装完成后立即添加prettier和eslint:
npm install --save-dev prettier eslint eslint-config-prettier- 配置.vscode/settings.json实现保存自动格式化:
{ "editor.formatOnSave": true, "editor.defaultFormatter": "esbenp.prettier-vscode" }2.2 后端服务搭建
Express服务我采用了分层架构:
project/ ├── server/ │ ├── controllers/ │ ├── models/ │ ├── routes/ │ ├── utils/ │ └── app.js └── client/ # 前端项目关键配置项:
// app.js const express = require('express') const cors = require('cors') const app = express() app.use(cors({ origin: 'http://localhost:5173' // Vite默认前端端口 })) app.use(express.json()) // 解析JSON请求体3. 数据库连接与CRUD实现
3.1 MongoDB连接优化
使用mongoose时的连接配置很有讲究:
const mongoose = require('mongoose') const connectDB = async () => { try { await mongoose.connect('mongodb://127.0.0.1:27017/learn-it', { useNewUrlParser: true, useUnifiedTopology: true, serverSelectionTimeoutMS: 5000, // 超时设置 maxPoolSize: 10 // 连接池大小 }) console.log('MongoDB connected') } catch (err) { console.error('Connection error', err) process.exit(1) } }3.2 用户模型设计示例
定义第一个模型时要注意验证规则:
const userSchema = new mongoose.Schema({ username: { type: String, required: true, unique: true, trim: true, minlength: 3, maxlength: 20, match: /^[a-zA-Z0-9_]+$/ // 只允许字母数字下划线 }, password: { type: String, required: true, minlength: 8, select: false // 查询时不返回 } }, { timestamps: true // 自动添加createdAt和updatedAt })4. 前后端联调实战
4.1 用户注册功能实现
前端表单提交要注意的几个坑:
- 必须处理loading状态防止重复提交
- 错误信息要友好展示
- 成功后的跳转逻辑
React组件示例:
function RegisterForm() { const [formData, setFormData] = useState({ username: '', password: '' }) const [error, setError] = useState(null) const [loading, setLoading] = useState(false) const handleSubmit = async (e) => { e.preventDefault() setLoading(true) try { const res = await fetch('http://localhost:3000/api/users', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(formData) }) if (!res.ok) throw new Error(await res.text()) // 注册成功后的处理 } catch (err) { setError(err.message) } finally { setLoading(false) } } // ...表单JSX }4.2 跨域问题深度解决
虽然前面配置了cors,但实际开发还会遇到:
- 预检请求(OPTIONS)处理
- 带凭证的请求(credentials)
- 自定义请求头的问题
终极解决方案:
// 后端中间件 app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', 'http://localhost:5173') res.header('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,OPTIONS') res.header('Access-Control-Allow-Headers', 'Content-Type,Authorization') res.header('Access-Control-Allow-Credentials', 'true') if (req.method === 'OPTIONS') return res.sendStatus(200) next() })5. 自学过程中的经验总结
5.1 高效学习的方法论
- 30分钟法则:遇到问题先自己尝试解决30分钟,还不行再查资料
- 文档优先原则:先看官方文档,再看博客文章
- 小步快跑:每完成一个小功能就commit代码
- 日报制度:每天记录学到的3个重点和1个待解决问题
5.2 常见踩坑记录
- 端口冲突:React默认3000,Express也常用3000,建议前端用5173
- 环境变量:前端项目使用.env文件要加VITE_前缀:
VITE_API_BASE_URL=http://localhost:3000 - 热更新失效:修改后端代码后要手动重启服务,可以安装nodemon:
npm install -g nodemon nodemon server.js
5.3 明日学习计划
根据今天遇到的问题,明天重点突破:
- JWT身份认证实现
- 前端路由保护(私有路由)
- 密码加密存储(bcrypt实战)
- 使用Postman测试API接口
自学IT最难的不是技术本身,而是保持持续学习的动力。我的经验是每天都要有可视化的成果产出,哪怕只是一个小小的功能点,这种正向反馈是坚持下去的关键。今天的项目虽然简单,但已经包含了现代Web开发的核心要素,后续可以在此基础上不断迭代完善。