使用Claude Code构建全栈项目:从零到部署的实战指南

2次阅读
没有评论

共计 4148 个字符,预计需要花费 11 分钟才能阅读完成。

image.webp

前言

作为刚接触全栈开发的新手,最头疼的莫过于如何将前后端有机结合起来。最近我用 Claude Code 完整走了一遍 Todo List 应用的开发流程,从架构设计到最终部署,收获颇丰。下面就把这个实战过程记录下来,希望能帮到同样在摸索的你。

使用 Claude Code 构建全栈项目:从零到部署的实战指南

1. 架构设计:从单体到分离

刚开始学习时,我习惯把前后端代码混在一起(单体架构),但随着功能增加,发现这种架构存在明显问题:

  • 前端任何改动都需要重新部署整个应用
  • 后端接口调整可能直接破坏前端功能
  • 团队协作时互相等待,效率低下

改用前后端分离架构后:

  • 前端:专注 UI 和交互,通过 API 获取数据
  • 后端:专注业务逻辑和数据持久化
  • 两者通过明确定义的接口契约进行通信

这种分离带来的好处是:

  1. 开发效率提升:前后端可以并行开发
  2. 技术栈自由:前端可以用 React/Vue,后端可以用 Java/Node
  3. 易于扩展:可以单独扩展前端或后端服务

2. 技术栈选择

根据 Claude Code 的建议,我选择了这套技术组合:

  • 前端:React + TypeScript
  • 组件化开发体验好
  • TypeScript 提供类型安全
  • 后端:Node.js + Express
  • JavaScript 全栈统一
  • 轻量级框架学习成本低
  • 数据库:MongoDB
  • 文档型数据库适合 Todo 场景
  • 不需要预先定义 schema

3. JWT 鉴权实现

安全是 Web 应用的基础。我们采用 JWT(JSON Web Token) 机制来实现身份验证:

sequenceDiagram
    participant 用户
    participant 前端
    participant 后端

    用户 ->> 前端: 输入用户名密码
    前端 ->> 后端: POST /api/auth/login
    后端 -->> 前端: 返回 JWT 令牌
    前端 ->> 前端: 存储 token 到 localStorage
    前端 ->> 后端: 携带 token 请求数据 (Authorization 头)
    后端 ->> 后端: 验证 token 有效性
    后端 -->> 前端: 返回请求的数据 

核心代码实现:

// auth.service.ts - 生成 Token
import jwt from 'jsonwebtoken';

export const generateToken = (userId: string): string => {
  return jwt.sign({ userId},
    process.env.JWT_SECRET!,
    {expiresIn: '30d'}
  );
};

// auth.middleware.ts - 验证 Token
export const authenticate = (
  req: Request,
  res: Response,
  next: NextFunction
) => {const token = req.header('Authorization')?.replace('Bearer', '');

  if (!token) {return res.status(401).json({ 
      code: 'UNAUTHORIZED', 
      message: '请提供认证 token' 
    });
  }

  try {const decoded = jwt.verify(token, process.env.JWT_SECRET!) as {userId: string;};
    req.userId = decoded.userId;
    next();} catch (err) {res.status(401).json({ 
      code: 'INVALID_TOKEN', 
      message: '无效的 token' 
    });
  }
};

4. Todo List 核心功能实现

后端 API 设计(符合 OpenAPI 3.0)

paths:
  /api/todos:
    get:
      summary: 获取当前用户的待办列表
      security:
        - bearerAuth: []
      responses:
        '200':
          description: 待办列表
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TodoList'
    post:
      summary: 创建新待办
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateTodoRequest'
      responses:
        '201':
          description: 创建成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TodoItem'

前端组件示例

// TodoList.tsx
import {useState, useEffect} from 'react';

type Todo = {
  _id: string;
  title: string;
  completed: boolean;
  createdAt: string;
};

export default function TodoList() {const [todos, setTodos] = useState<Todo[]>([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {const fetchTodos = async () => {
      try {
        const res = await fetch('/api/todos', {
          headers: {'Authorization': `Bearer ${localStorage.getItem('token')}`
          }
        });

        if (!res.ok) throw new Error('获取数据失败');

        const data = await res.json();
        setTodos(data);
      } catch (err) {console.error(err);
      } finally {setLoading(false);
      }
    };

    fetchTodos();}, []);

  if (loading) return <div> 加载中...</div>;

  return (
    <div>
      <h2> 我的待办 </h2>
      <ul>
        {todos.map(todo => (<li key={todo._id}>
            <input 
              type="checkbox" 
              checked={todo.completed}
              onChange={() => toggleTodo(todo._id)}
            />
            {todo.title}
          </li>
        ))}
      </ul>
    </div>
  );
}

5. Docker 化部署

使用 Docker Compose 编排服务,简化部署流程:

version: '3.8'

services:
  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
    ports:
      - "3000:3000"
    depends_on:
      - backend

  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
    ports:
      - "5000:5000"
    environment:
      - MONGO_URI=mongodb://mongo:27017/todoapp
      - JWT_SECRET=your_secure_secret
    depends_on:
      - mongo

  mongo:
    image: mongo:5.0
    ports:
      - "27017:27017"
    volumes:
      - mongo-data:/data/db

volumes:
  mongo-data:

启动命令:

docker-compose up -d --build

6. 生产环境配置

Nginx 反向代理配置

server {
    listen 80;
    server_name yourdomain.com;

    location / {
        proxy_pass http://frontend:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    location /api {
        proxy_pass http://backend:5000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

性能优化建议

  1. 数据库索引:

    // 在 MongoDB 中为常用查询字段创建索引
    db.todos.createIndex({userId: 1, completed: 1});

  2. 接口缓存:

    // 使用 redis 缓存热门数据
    import redis from 'redis';
    const client = redis.createClient();
    
    app.get('/api/todos', async (req, res) => {const cacheKey = `todos:${req.userId}`;
    
      client.get(cacheKey, async (err, data) => {if (data) return res.json(JSON.parse(data));
    
        const todos = await Todo.find({userId: req.userId});
        client.setex(cacheKey, 3600, JSON.stringify(todos)); // 缓存 1 小时
        res.json(todos);
      });
    });

7. 常见问题排查

问题 1 :前端请求后端 API 出现 CORS 错误

解决方法:

// 后端添加 CORS 中间件
import cors from 'cors';

app.use(cors({
  origin: process.env.FRONTEND_URL || 'http://localhost:3000',
  credentials: true
}));

问题 2 :MongoDB 连接失败

检查点:

  1. MongoDB 服务是否启动
  2. 连接字符串是否正确
  3. 网络防火墙是否放行 27017 端口

结语

通过这个 Todo List 项目的完整实践,我深刻体会到前后端分离架构的优势。虽然初期配置可能稍显复杂,但一旦架构搭建完成,后续的开发效率会大幅提升。

建议你在实际开发中:

  1. 先定义好 API 契约(OpenAPI 规范)
  2. 前后端并行开发,通过 Mock 数据联调
  3. 尽早引入 Docker 简化环境配置
  4. 重视错误处理和日志记录

完整的项目代码已放在 GitHub 上,欢迎参考和指正。希望这篇指南能帮你少走弯路,快速掌握全栈开发的核心技能!

正文完
 0
评论(没有评论)