用 Claude Code 十分钟搭建全栈项目:从零到部署全流程
本文演示如何用 Claude Code CLI 在 10 分钟内搭建一个完整的全栈项目:FastAPI 后端 + React 前端 + PostgreSQL 数据库 + Docker 部署配置。每一步都展示实际的 Claude Code 对话命令和生成结果。
项目目标
搭建一个"待办事项"应用(Todo App),包含:
- 后端:FastAPI + SQLAlchemy + PostgreSQL
- 前端:React + TypeScript + Tailwind CSS
- 功能:用户注册/登录、CRUD 待办事项、标签分类
- 部署:Docker Compose 一键启动
第 1 分钟:项目初始化
创建项目目录并启动 Claude Code
mkdir todo-app && cd todo-app claude下达初始化指令
> 初始化一个全栈项目,后端用 FastAPI + SQLAlchemy + PostgreSQL, 前端用 React + TypeScript + Tailwind CSS。 创建标准的项目目录结构和配置文件。Claude Code 会自动执行以下操作:
# Claude Code 自动生成的目录结构 todo-app/ ├── backend/ │ ├── app/ │ │ ├── __init__.py │ │ ├── main.py │ │ ├── config.py │ │ ├── database.py │ │ ├── models/ │ │ ├── schemas/ │ │ ├── routers/ │ │ ├── services/ │ │ └── middleware/ │ ├── requirements.txt │ ├── Dockerfile │ └── alembic.ini ├── frontend/ │ ├── src/ │ │ ├── components/ │ │ ├── pages/ │ │ ├── hooks/ │ │ ├── services/ │ │ ├── types/ │ │ └── App.tsx │ ├── package.json │ ├── tailwind.config.js │ ├── tsconfig.json │ └── Dockerfile ├── docker-compose.yml ├── CLAUDE.md └── .gitignore注意 Claude Code 会自动创建 CLAUDE.md 文件,记录项目约定,方便后续会话快速理解项目。
第 2-3 分钟:后端 API 开发
生成数据库模型
> 创建数据库模型: 1. User: id, email, hashed_password, username, created_at 2. Todo: id, title, description, completed, priority(1-5), due_date, user_id, created_at 3. Tag: id, name, color 4. todo_tags 多对多关联表 用 SQLAlchemy ORM,支持软删除。Claude Code 生成的模型代码(节选):
# backend/app/models/todo.py from sqlalchemy import Column, Integer, String, Boolean, DateTime, ForeignKey, Table from sqlalchemy.orm import relationship from datetime import datetime from app.database import Base todo_tags = Table( "todo_tags", Base.metadata, Column("todo_id", Integer, ForeignKey("todos.id"), primary_key=True), Column("tag_id", Integer, ForeignKey("tags.id"), primary_key=True), ) class Todo(Base): __tablename__ = "todos" id = Column(Integer, primary_key=True, index=True) title = Column(String(200), nullable=False) description = Column(String(1000), default="") completed = Column(Boolean, default=False) priority = Column(Integer, default=3) due_date = Column(DateTime, nullable=True) user_id = Column(Integer, ForeignKey("users.id"), nullable=False) created_at = Column(DateTime, default=datetime.utcnow) deleted_at = Column(DateTime, nullable=True) # 软删除 user = relationship("User", back_populates="todos") tags = relationship("Tag", secondary=todo_tags, back_populates="todos")生成 API 路由
> 为 Todo 模型创建完整的 CRUD API: - POST /api/todos - 创建 - GET /api/todos - 列表(支持分页、过滤、排序) - GET /api/todos/{id} - 详情 - PUT /api/todos/{id} - 更新 - DELETE /api/todos/{id} - 删除(软删除) - PATCH /api/todos/{id}/toggle - 切换完成状态 所有接口需要 JWT 认证。Claude Code 自动生成 router、service、schema 三层代码:
# backend/app/routers/todos.py (节选) from fastapi import APIRouter, Depends, Query from sqlalchemy.orm import Session from typing import Optional from app.schemas.todo import TodoCreate, TodoUpdate, TodoResponse, TodoList from app.services.todo_service import TodoService from app.middleware.auth import get_current_user router = APIRouter(prefix="/api/todos", tags=["todos"]) @router.get("", response_model=TodoList) async def list_todos( page: int = Query(1, ge=1), page_size: int = Query(20, ge=1, le=100), completed: Optional[bool] = None, priority: Optional[int] = None, sort_by: str = Query("created_at", regex="^(created_at|priority|due_date)$"), order: str = Query("desc", regex="^(asc|desc)$"), db: Session = Depends(get_db), current_user = Depends(get_current_user), ): return TodoService.list_todos( db, current_user.id, page, page_size, completed=completed, priority=priority, sort_by=sort_by, order=order, )第 4-5 分钟:用户认证
> 实现 JWT 认证系统: - POST /api/auth/register - 注册(email + password + username) - POST /api/auth/login - 登录(返回 access_token + refresh_token) - POST /api/auth/refresh - 刷新 token - GET /api/auth/me - 获取当前用户信息 密码用 bcrypt 加密,token 有效期 access=30min, refresh=7days。Claude Code 会自动生成完整的认证模块,包括密码哈希、JWT 编解码、中间件等。
第 5-7 分钟:前端开发
初始化 React 项目
> 初始化前端 React 项目,安装依赖,配置 Tailwind CSS。 创建以下页面: 1. 登录/注册页 2. Todo 列表主页(支持过滤和排序) 3. 创建/编辑 Todo 弹窗 使用 React Router v6 + Axios + React Query。Claude Code 生成的前端代码(TodoList 组件节选):
// frontend/src/pages/TodoList.tsx import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { todoApi } from '../services/api'; import { TodoCard } from '../components/TodoCard'; import { CreateTodoModal } from '../components/CreateTodoModal'; import { useState } from 'react'; export function TodoList() { const [filter, setFilter] = useState({ completed: undefined, priority: undefined }); const [showCreate, setShowCreate] = useState(false); const queryClient = useQueryClient(); const { data, isLoading } = useQuery({ queryKey: ['todos', filter], queryFn: () => todoApi.list(filter), }); const toggleMutation = useMutation({ mutationFn: (id: number) => todoApi.toggle(id), onSuccess: () => queryClient.invalidateQueries({ queryKey: ['todos'] }), }); return ( <div className="max-w-4xl mx-auto p-6"> <div className="flex justify-between items-center mb-8"> <h1 className="text-3xl font-bold text-gray-900">我的待办</h1> <button onClick={() => setShowCreate(true)} className="bg-teal-600 text-white px-4 py-2 rounded-lg hover:bg-teal-700" > 新建待办 </button> </div> {/* 过滤器和列表渲染 */} </div> ); }配置 API 请求
> 创建 Axios 实例,配置请求/响应拦截器, 自动附加 JWT token,处理 401 自动刷新 token。// frontend/src/services/api.ts import axios from 'axios'; const api = axios.create({ baseURL: import.meta.env.VITE_API_URL || 'http://localhost:8000', }); api.interceptors.request.use((config) => { const token = localStorage.getItem('access_token'); if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; }); api.interceptors.response.use( (res) => res, async (error) => { if (error.response?.status === 401) { const refreshToken = localStorage.getItem('refresh_token'); if (refreshToken) { const { data } = await axios.post('/api/auth/refresh', { refreshToken }); localStorage.setItem('access_token', data.accessToken); error.config.headers.Authorization = `Bearer ${data.accessToken}`; return api(error.config); } } return Promise.reject(error); } );第 7-8 分钟:测试
> 为后端 API 生成单元测试,覆盖 CRUD 和认证流程。 使用 pytest + httpx,mock 数据库。# backend/tests/test_todos.py (节选) import pytest from httpx import AsyncClient from app.main import app @pytest.mark.asyncio async def test_create_todo(auth_client: AsyncClient): response = await auth_client.post("/api/todos", json={ "title": "测试待办", "description": "这是一条测试", "priority": 3, }) assert response.status_code == 201 data = response.json() assert data["title"] == "测试待办" assert data["completed"] is False @pytest.mark.asyncio async def test_list_todos_with_filter(auth_client: AsyncClient): # 创建多条测试数据 for i in range(5): await auth_client.post("/api/todos", json={ "title": f"待办 {i}", "priority": i % 5 + 1, "completed": i % 2 == 0, }) # 测试过滤 response = await auth_client.get("/api/todos?completed=false&priority=2") assert response.status_code == 200 data = response.json() assert all(not t["completed"] for t in data["list"]) @pytest.mark.asyncio async def test_toggle_todo(auth_client: AsyncClient): # 创建 res = await auth_client.post("/api/todos", json={"title": "Toggle 测试"}) todo_id = res.json()["id"] # 切换 res = await auth_client.patch(f"/api/todos/{todo_id}/toggle") assert res.json()["completed"] is True # 再次切换 res = await auth_client.patch(f"/api/todos/{todo_id}/toggle") assert res.json()["completed"] is False第 8-9 分钟:Docker 部署配置
> 生成 Docker Compose 配置,包含后端、前端、PostgreSQL、Redis。 后端使用 uvicorn 运行,前端用 nginx 托管静态文件。 配置健康检查和自动重启。# docker-compose.yml version: '3.8' services: postgres: image: postgres:16-alpine environment: POSTGRES_USER: todoapp POSTGRES_PASSWORD: todoapp123 POSTGRES_DB: todoapp volumes: - postgres_data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U todoapp"] interval: 10s timeout: 5s retries: 5 redis: image: redis:7-alpine healthcheck: test: ["CMD", "redis-cli", "ping"] backend: build: ./backend ports: - "8000:8000" environment: DATABASE_URL: postgresql://todoapp:todoapp123@postgres:5432/todoapp REDIS_URL: redis://redis:6379 JWT_SECRET: your-secret-key-change-in-production depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped frontend: build: ./frontend ports: - "3000:80" depends_on: - backend restart: unless-stopped volumes: postgres_data:第 9-10 分钟:收尾与启动
生成 CLAUDE.md
> 生成 CLAUDE.md 项目说明文件,记录项目架构、开发约定、常用命令。初始化 Git 并启动
> 初始化 Git 仓库,创建 .gitignore,做第一次 commit。 然后启动 docker-compose 验证一切正常。# Claude Code 执行的命令 git init git add . git commit -m "feat: 初始化 Todo App 全栈项目 - FastAPI 后端 + SQLAlchemy ORM - React + TypeScript + Tailwind CSS 前端 - JWT 认证系统 - Docker Compose 部署配置 - 单元测试覆盖" # 启动项目 docker-compose up -d # 运行数据库迁移 docker-compose exec backend alembic upgrade head # 验证 curl http://localhost:8000/api/health # {"status": "ok", "database": "connected"}最终项目统计
| 模块 | 文件数 | 代码行数 |
|---|---|---|
| 后端 API | 18 | ~850 行 |
| 前端 React | 15 | ~1200 行 |
| 测试 | 4 | ~300 行 |
| 配置文件 | 8 | ~200 行 |
| 总计 | 45 | ~2550 行 |
经验总结
- 指令要具体:明确技术栈、字段定义、功能细节,Claude Code 才能一次生成正确
- 分步推进:不要一次下达所有需求,按模块分步骤更可控
- 先写 CLAUDE.md:项目约定越清晰,后续生成的代码质量越高
- 善用 @ 引用:用
@filename让 Claude Code 关注特定文件 - 及时验证:每生成一个模块就运行测试,发现问题立即修复
总结
Claude Code 将全栈项目的初始化效率提升了 10 倍以上。10 分钟内完成的工作,手动编写可能需要 2-3 天。关键不是"AI 写了所有代码",而是"AI 帮你跳过了所有重复性的脚手架工作",让你可以把精力集中在业务逻辑上。
接口配置参考:https://9m8m.com/docs/
