首页 › tutorials › Claude Code前端开发实战:React七步高效交付

Claude Code前端开发实战:React+TypeScript七步高效交付

概述

本教程面向具备React和TypeScript基础的前端开发者,系统讲解如何利用Claude Code CLI工具完成从项目脚手架搭建、组件架构设计、状态管理选型、API数据对接、样式系统构建、自动化测试到生产构建的完整前端工作流。学完后,你将掌握一条经过实战验证的Claude Code前端开发高效交付路径。

适用人群:有6个月以上React经验,想用AI工具提升前端开发效率的中高级开发者。

前置条件

条件 说明
Node.js 20.x LTS 或更高版本
包管理器 pnpm 9.x(推荐)或 npm 10.x
Claude Code @anthropic-ai/claude-code 最新版
React知识 函数组件、Hooks、基础TypeScript
操作系统 macOS / Linux / WSL2

确认Claude Code已就绪:

claude --version
# 预期输出: 1.0.x 或更高

第一步:项目脚手架与CLAUDE.md配置

1.1 创建项目

用Vite创建React+TypeScript项目,这是目前最快的前端构建工具链:

pnpm create vite task-dashboard --template react-ts
cd task-dashboard
pnpm install

1.2 编写项目级CLAUDE.md

CLAUDE.md是Claude Code理解你项目的核心入口。一个专业的前端项目CLAUDE.md应该包含技术栈约定、目录规范和编码风格:

# Task Dashboard

## Tech Stack
- React 19 + TypeScript 5.6 (strict mode)
- Vite 6 for build tooling
- Tailwind CSS 4 for styling
- Zustand for client state
- TanStack Query v5 for server state
- React Router v7 for routing
- Vitest + React Testing Library for tests

## Project Structure
src/
├── components/     # 可复用UI组件(按功能分子目录)
│   ├── ui/        # 基础原子组件(Button, Input, Modal...)
│   ├── layout/    # 布局组件(Header, Sidebar, Footer...)
│   └── features/  # 业务功能组件(TaskList, TaskCard...)
├── hooks/         # 自定义Hooks
├── stores/        # Zustand stores
├── services/      # API调用层
├── types/         # TypeScript类型定义
├── utils/         # 工具函数
└── pages/         # 路由页面组件

## Code Conventions
- 组件用PascalCase命名,文件名用PascalCase.tsx
- Hooks用use前缀,文件名用camelCase.ts
- 优先使用named export,仅在页面组件用default export
- Props接口定义在组件文件内部,不单独建types文件(除非跨组件复用)
- 样式用Tailwind class,禁止内联style
- 所有组件必须包含TypeScript类型,禁止any

## Commands
- `pnpm dev` — 启动开发服务器
- `pnpm build` — 生产构建
- `pnpm test` — 运行测试
- `pnpm lint` — ESLint检查
- `pnpm type-check` — TypeScript类型检查

## Testing Rules
- 测试文件放在被测组件同级目录: Component.tsx → Component.test.tsx
- 用Vitest + React Testing Library
- 测试用户行为,不测试实现细节
- 每个组件至少覆盖: 渲染正确、用户交互、边界状态

1.3 安装核心依赖

在Claude Code中执行:

claude

进入交互模式后输入:

根据CLAUDE.md中的技术栈,安装所有需要的依赖包。包括:
Tailwind CSS 4, Zustand, TanStack Query v5, React Router v7, Vitest, React Testing Library, 以及它们的TypeScript类型定义。配置好tailwind和vitest。

Claude Code会自动执行以下操作(预期结果):

✓ 安装 tailwindcss @tailwindcss/vite zustand @tanstack/react-query react-router
✓ 安装 -D vitest @testing-library/react @testing-library/jest-dom jsdom
✓ 配置 vite.config.ts 集成 Tailwind 和 Vitest
✓ 创建 src/index.css 引入 Tailwind
✓ 配置 tsconfig.json 的 types 字段包含 vitest/globals

常见问题

Q: Claude Code安装了错误版本的包 在CLAUDE.md中明确版本号,如 "zustand": "^5.0.0"。Claude Code会参考你指定的版本。

Q: Tailwind配置与Vite不兼容 Tailwind CSS v4使用@tailwindcss/vite插件,不再需要tailwind.config.js。确保Claude Code安装的是v4版本。

第二步:组件架构设计与原子组件生成

2.1 建立组件规范

在Claude Code中建立组件架构时,采用原子设计(Atomic Design)方法论,让Claude Code按层级生成组件:

帮我创建一套UI基础原子组件,放在 src/components/ui/ 目录下。

需要以下组件,每个组件遵循以下规范:
1. 完整的TypeScript Props类型定义
2. 支持forwardRef
3. 支持className合并(用clsx)
4. 包含variants(用class-variance-authority)
5. 同目录下有对应的.test.tsx测试文件

组件列表:
- Button: primary/secondary/danger/ghost四种variant,sm/md/lg三种size
- Input: 支持label, error, disabled状态
- Badge: 支持不同颜色主题
- Card: 支持header/body/footer分区
- Modal: 支持打开/关闭动画,点击外部关闭

2.2 预期生成的Button组件示例

Claude Code生成的组件会遵循你的CLAUDE.md约定,输出类似:

// src/components/ui/Button.tsx
import { forwardRef } from 'react';
import { cva, type VariantProps } from 'class-variance-authority';
import { cn } from '@/utils/cn';

const buttonVariants = cva(
  'inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
  {
    variants: {
      variant: {
        primary: 'bg-blue-600 text-white hover:bg-blue-700',
        secondary: 'bg-gray-100 text-gray-900 hover:bg-gray-200',
        danger: 'bg-red-600 text-white hover:bg-red-700',
        ghost: 'hover:bg-gray-100 text-gray-700',
      },
      size: {
        sm: 'h-8 px-3 text-sm',
        md: 'h-10 px-4 text-sm',
        lg: 'h-12 px-6 text-base',
      },
    },
    defaultVariants: {
      variant: 'primary',
      size: 'md',
    },
  }
);

interface ButtonProps
  extends React.ButtonHTMLAttributes<HTMLButtonElement>,
    VariantProps<typeof buttonVariants> {}

const Button = forwardRef<HTMLButtonElement, ButtonProps>(
  ({ className, variant, size, ...props }, ref) => {
    return (
      <button
        className={cn(buttonVariants({ variant, size, className }))}
        ref={ref}
        {...props}
      />
    );
  }
);
Button.displayName = 'Button';

export { Button, buttonVariants };
export type { ButtonProps };

2.3 批量生成策略

当需要一次性生成多个组件时,使用分批策略避免Claude Code上下文溢出:

第一批: 生成 Button, Input, Badge(基础表单组件)
第二批: 生成 Card, Modal, Dialog(容器组件)
第三批: 生成 DataTable, Pagination(复合组件)

每批生成后立即运行测试验证:

pnpm test src/components/ui/

常见问题

Q: 生成的组件样式不一致 在CLAUDE.md中添加设计令牌(Design Tokens)章节,定义颜色、圆角、间距的统一规范。或者引入shadcn/ui作为基础组件库。

Q: 组件缺少边界case处理 追加提示词:请补充处理 loading、error、disabled、empty 四种状态的UI表现。

第三步:状态管理方案与API层构建

3.1 双层状态架构

现代React应用推荐双层状态管理架构:

graph TB
    subgraph Server["服务端状态层"]
        A[React Query / TanStack Query] --> B[缓存管理]
        A --> C[自动重新获取]
        A --> D[乐观更新]
        A --> E[轮询与分页]
    end

    subgraph Client["客户端状态层"]
        F[Zustand Store] --> G[UI状态]
        F --> H[用户偏好]
        F --> I[表单临时数据]
        F --> J[全局通知]
    end

    subgraph API["API调用层"]
        K[fetch封装] --> L[请求拦截]
        K --> M[响应处理]
        K --> N[错误统一处理]
    end

    Server --> API
    Client -.->|触发mutation| Server

3.2 用Claude Code构建API Service层

在Claude Code中输入:

创建 src/services/api.ts,实现以下功能:
1. 基于fetch的HTTP客户端封装
2. 自动添加Content-Type: application/json
3. 统一错误处理,抛出自定义ApiError
4. 请求/响应拦截器模式
5. 支持请求取消(AbortController)

然后创建 src/services/taskService.ts,实现Task的CRUD:
- getTasks(filters?): GET /api/tasks
- getTaskById(id): GET /api/tasks/:id
- createTask(data): POST /api/tasks
- updateTask(id, data): PATCH /api/tasks/:id
- deleteTask(id): DELETE /api/tasks/:id

Task类型定义在 src/types/task.ts:
interface Task {
  id: string;
  title: string;
  description?: string;
  status: 'todo' | 'in_progress' | 'done';
  priority: 'low' | 'medium' | 'high';
  assignee?: string;
  dueDate?: string;
  createdAt: string;
  updatedAt: string;
}

3.3 构建TanStack Query Hooks

基于 taskService 创建 src/hooks/useTaskQueries.ts,使用 TanStack Query v5:

1. useTasks(filters?) - 查询任务列表,支持过滤参数
2. useTask(id) - 查询单个任务
3. useCreateTask() - 创建任务mutation,创建后自动刷新列表
4. useUpdateTask() - 更新任务mutation,乐观更新
5. useDeleteTask() - 删除任务mutation,删除后从缓存移除

要求:
- 所有query使用queryKey工厂模式
- createTask成功后使相关query失效
- updateTask使用乐观更新,失败时回滚
- deleteTask成功后从缓存移除该项
- 错误处理通过全局toast通知用户

Claude Code生成的queryKey工厂模式:

// src/hooks/useTaskQueries.ts
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import * as taskService from '@/services/taskService';
import type { Task, CreateTaskInput, UpdateTaskInput } from '@/types/task';

// Query Key 工厂 — 集中管理缓存键
export const taskKeys = {
  all: ['tasks'] as const,
  lists: () => [...taskKeys.all, 'list'] as const,
  list: (filters?: Record<string, unknown>) =>
    [...taskKeys.lists(), filters] as const,
  details: () => [...taskKeys.all, 'detail'] as const,
  detail: (id: string) => [...taskKeys.details(), id] as const,
};

export function useTasks(filters?: Record<string, unknown>) {
  return useQuery({
    queryKey: taskKeys.list(filters),
    queryFn: () => taskService.getTasks(filters),
  });
}

export function useTask(id: string) {
  return useQuery({
    queryKey: taskKeys.detail(id),
    queryFn: () => taskService.getTaskById(id),
    enabled: !!id,
  });
}

export function useCreateTask() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (data: CreateTaskInput) => taskService.createTask(data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: taskKeys.lists() });
    },
  });
}

export function useUpdateTask() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: ({ id, data }: { id: string; data: UpdateTaskInput }) =>
      taskService.updateTask(id, data),
    onMutate: async ({ id, data }) => {
      await queryClient.cancelQueries({ queryKey: taskKeys.detail(id) });
      const previousTask = queryClient.getQueryData<Task>(taskKeys.detail(id));
      queryClient.setQueryData(taskKeys.detail(id), (old: Task) => ({
        ...old,
        ...data,
      }));
      return { previousTask };
    },
    onError: (_err, { id }, context) => {
      queryClient.setQueryData(taskKeys.detail(id), context?.previousTask);
    },
    onSettled: () => {
      queryClient.invalidateQueries({ queryKey: taskKeys.lists() });
    },
  });
}

export function useDeleteTask() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (id: string) => taskService.deleteTask(id),
    onSuccess: (_data, deletedId) => {
      queryClient.removeQueries({ queryKey: taskKeys.detail(deletedId) });
      queryClient.invalidateQueries({ queryKey: taskKeys.lists() });
    },
  });
}

3.4 构建Zustand客户端状态Store

创建 src/stores/uiStore.ts,用Zustand管理:
1. sidebarOpen: boolean — 侧边栏展开/折叠
2. theme: 'light' | 'dark' — 主题切换
3. notifications: Notification[] — 全局通知队列
4. addNotification(message, type): 添加通知并3秒后自动移除
5. removeNotification(id): 手动移除通知

要求:
- 使用persist middleware持久化theme到localStorage
- 使用immer middleware支持不可变更新
- 导出独立的selector函数,避免不必要的re-render

常见问题

Q: TanStack Query缓存键冲突 始终使用queryKey工厂模式(如上面的taskKeys),不要手写字符串数组。

Q: Zustand store导致频繁re-render 为每个状态切片导出独立的selector:

// 错误:订阅整个store
const { sidebarOpen, theme } = useUIStore();

// 正确:只订阅需要的状态
const sidebarOpen = useUIStore((s) => s.sidebarOpen);
const theme = useUIStore((s) => s.theme);

第四步:页面组件与路由搭建

4.1 路由配置

使用React Router v7配置以下路由,创建 src/router.tsx:

路由结构:
/ → DashboardPage(任务统计面板)
/tasks → TaskListPage(任务列表,支持筛选排序)
/tasks/:id → TaskDetailPage(任务详情)
/tasks/new → TaskFormPage(创建新任务)
/settings → SettingsPage(用户设置)

要求:
- 使用createBrowserRouter + RouterProvider
- 实现Lazy Loading(React.lazy + Suspense)
- 添加Layout组件包裹所有页面(Header + Sidebar + Main)
- 添加404页面兜底
- 添加全局Loading Spinner

4.2 预期路由配置

// src/router.tsx
import { createBrowserRouter, Navigate } from 'react-router';
import { lazy, Suspense } from 'react';
import { Layout } from '@/components/layout/Layout';
import { LoadingSpinner } from '@/components/ui/LoadingSpinner';

const Lazy = (Component: React.LazyExoticComponent<React.ComponentType>) => (
  <Suspense fallback={<LoadingSpinner />}>
    <Component />
  </Suspense>
);

export const router = createBrowserRouter([
  {
    element: <Layout />,
    children: [
      { index: true, element: Lazy(lazy(() => import('@/pages/DashboardPage'))) },
      { path: 'tasks', element: Lazy(lazy(() => import('@/pages/TaskListPage'))) },
      { path: 'tasks/:id', element: Lazy(lazy(() => import('@/pages/TaskDetailPage'))) },
      { path: 'tasks/new', element: Lazy(lazy(() => import('@/pages/TaskFormPage'))) },
      { path: 'settings', element: Lazy(lazy(() => import('@/pages/SettingsPage'))) },
      { path: '404', element: Lazy(lazy(() => import('@/pages/NotFoundPage'))) },
      { path: '*', element: <Navigate to="/404" replace /> },
    ],
  },
]);

4.3 页面组件开发

以任务列表页为例,向Claude Code描述页面需求:

创建 src/pages/TaskListPage.tsx,实现一个任务管理列表页面:

功能:
1. 顶部搜索栏(实时过滤任务标题)
2. 状态筛选Tab(全部/待办/进行中/已完成)
3. 优先级下拉筛选
4. 任务卡片网格布局(响应式:移动端1列,平板2列,桌面3列)
5. 每张任务卡片显示:标题、优先级Badge、负责人头像、截止日期
6. 卡片点击跳转到详情页
7. 右下角浮动"新建任务"按钮
8. 空状态展示(无任务时显示引导插图)
9. 加载状态展示骨架屏

使用已有的 useTasks hook 获取数据。
使用已有的 UI 组件(Button, Input, Badge, Card)。
样式使用Tailwind CSS。

常见问题

Q: 懒加载导致页面闪烁 为Suspense提供与页面结构一致的骨架屏fallback,而非简单的Loading文字。

Q: 路由守卫实现 在Layout组件中用useEffect检查认证状态,未登录时重定向到登录页。

第五步:样式系统与响应式设计

5.1 Tailwind主题定制

在 src/index.css 中配置 Tailwind CSS v4 主题:

自定义设计令牌:
- 主色调: blue-600 (#2563EB)
- 成功色: green-500
- 警告色: amber-500
- 危险色: red-500
- 圆角: 默认8px, 大号12px
- 阴影: sm/md/lg三档
- 动画: 添加fade-in和slide-up两个自定义动画

字体:
- 中文: system-ui, -apple-system, "PingFang SC"
- 代码: "JetBrains Mono", monospace

Tailwind CSS v4使用CSS-first配置,预期输出:

/* src/index.css */
@import "tailwindcss";

@theme {
  --color-primary: #2563EB;
  --color-primary-hover: #1D4ED8;
  --color-success: #22C55E;
  --color-warning: #F59E0B;
  --color-danger: #EF4444;

  --radius-default: 8px;
  --radius-lg: 12px;

  --shadow-card: 0 1px 3px rgba(0, 0, 0, 0.1);
  --shadow-elevated: 0 4px 12px rgba(0, 0, 0, 0.1);

  --animate-fade-in: fade-in 0.2s ease-out;
  --animate-slide-up: slide-up 0.3s ease-out;

  --font-sans: system-ui, -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif;
  --font-mono: "JetBrains Mono", "Fira Code", monospace;
}

@keyframes fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes slide-up {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}

5.2 响应式断点规范

在CLAUDE.md中明确响应式策略,让Claude Code生成一致的响应式代码:

## Responsive Breakpoints
- sm: 640px (手机横屏)
- md: 768px (平板竖屏)
- lg: 1024px (平板横屏/小笔记本)
- xl: 1280px (桌面)
- 2xl: 1536px (大屏桌面)

策略: Mobile First,默认写移动端样式,用sm/md/lg/xl递增。

常见问题

Q: Claude Code生成的Tailwind类名顺序混乱 安装prettier-plugin-tailwindcss,Claude Code通常会自动识别并遵循Prettier配置。

Q: 暗黑模式支持 在Tailwind主题中添加--dark-mode: class,并在Zustand store中管理主题状态,切换时给<html>添加dark类名。

第六步:自动化测试策略

6.1 Vitest配置

Claude Code通常在第一步就会帮你配置好Vitest,但你需要明确测试策略。在CLAUDE.md中添加测试规范后,让Claude Code生成测试:

为 src/components/ui/Button.tsx 生成完整的测试文件 Button.test.tsx。

测试要求:
1. 渲染测试:正确渲染文本内容
2. Variant测试:四种variant都有正确的CSS类名
3. Size测试:三种size都有正确的CSS类名
4. 交互测试:点击事件正确触发
5. 禁用测试:disabled状态下不可点击
6. Ref转发测试:forwardRef正确工作
7. 类名合并测试:自定义className正确合并

使用 Vitest + React Testing Library。
不要使用已废弃的act()包装,用screen和userEvent。

6.2 预期测试输出

// src/components/ui/Button.test.tsx
import { describe, it, expect, vi } from 'vitest';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { Button } from './Button';

describe('Button', () => {
  it('renders children text', () => {
    render(<Button>Click me</Button>);
    expect(screen.getByRole('button', { name: 'Click me' })).toBeInTheDocument();
  });

  it.each([
    ['primary', 'bg-blue-600'],
    ['secondary', 'bg-gray-100'],
    ['danger', 'bg-red-600'],
    ['ghost', 'hover:bg-gray-100'],
  ] as const)('applies %s variant styles', (variant, expectedClass) => {
    render(<Button variant={variant}>{variant}</Button>);
    const button = screen.getByRole('button');
    expect(button.className).toContain(expectedClass);
  });

  it('calls onClick when clicked', async () => {
    const onClick = vi.fn();
    const user = userEvent.setup();
    render(<Button onClick={onClick}>Click</Button>);
    await user.click(screen.getByRole('button'));
    expect(onClick).toHaveBeenCalledOnce();
  });

  it('does not call onClick when disabled', async () => {
    const onClick = vi.fn();
    const user = userEvent.setup();
    render(<Button disabled onClick={onClick}>Disabled</Button>);
    await user.click(screen.getByRole('button'));
    expect(onClick).not.toHaveBeenCalled();
  });

  it('forwards ref to button element', () => {
    const ref = { current: null };
    render(<Button ref={ref}>Ref</Button>);
    expect(ref.current).toBeInstanceOf(HTMLButtonElement);
  });

  it('merges custom className', () => {
    render(<Button className="my-custom">Custom</Button>);
    expect(screen.getByRole('button').className).toContain('my-custom');
  });
});

6.3 测试Hooks和API层

为 src/hooks/useTaskQueries.ts 生成测试 useTaskQueries.test.ts。

要求:
1. Mock taskService的所有方法
2. 用 @tanstack/react-query 的 QueryClientWrapper 包裹
3. 测试 useTasks 成功获取数据
4. 测试 useCreateTask 成功后自动刷新列表
5. 测试 useUpdateTask 乐观更新和错误回滚
6. 测试 useDeleteTask 成功后移除缓存
7. 使用 waitFor 等待异步状态更新

6.4 运行全量测试

pnpm test

如果测试失败,让Claude Code自动修复:

运行 pnpm test,修复所有失败的测试。不要修改测试用例的期望值,修改实现代码使其通过测试。

常见问题

Q: 测试中TanStack Query报错 "No QueryClient set" 创建测试用的Wrapper:

function createQueryWrapper() {
  const queryClient = new QueryClient({
    defaultOptions: { queries: { retry: false } },
  });
  return function Wrapper({ children }: { children: React.ReactNode }) {
    return (
      <QueryClientProvider client={queryClient}>
        {children}
      </QueryClientProvider>
    );
  };
}

Q: 测试运行太慢 在vitest.config.ts中启用pool: 'forks'和poolOptions: { forks: { singleFork: true } }。

第七步:生产构建与部署

7.1 构建优化配置

优化 vite.config.ts 的生产构建配置:

1. 手动分包策略(vendor chunks):
   - react/react-dom 打一个包
   - react-router 打一个包
   - tanstack-query 打一个包
   - zustand 打一个包
   - UI组件打一个包

2. 开启 gzip 压缩报告

3. 图片资源优化(小于4kb内联,大于4kb生成文件)

4. 配置路径别名 @/ 映射到 src/

5. 配置开发代理 /api → http://localhost:3001

预期vite.config.ts:

// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import tailwindcss from '@tailwindcss/vite';
import { resolve } from 'path';

export default defineConfig({
  plugins: [react(), tailwindcss()],
  resolve: {
    alias: {
      '@': resolve(__dirname, './src'),
    },
  },
  server: {
    proxy: {
      '/api': {
        target: 'http://localhost:3001',
        changeOrigin: true,
      },
    },
  },
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          'vendor-react': ['react', 'react-dom'],
          'vendor-router': ['react-router'],
          'vendor-query': ['@tanstack/react-query'],
          'vendor-state': ['zustand'],
        },
      },
    },
    reportCompressedSize: true,
  },
});

7.2 部署前检查清单

让Claude Code执行完整的部署前验证:

执行以下部署前检查并报告结果:
1. pnpm type-check — TypeScript类型检查,0错误
2. pnpm lint — ESLint检查,0警告
3. pnpm test — 全部测试通过
4. pnpm build — 构建成功
5. 分析构建产物大小,报告各chunk体积
6. 检查是否有未使用的依赖(depcheck)

7.3 部署到Vercel/Netlify

配置部署到 Vercel:
1. 创建 vercel.json 配置SPA路由重写(所有路由→index.html)
2. 配置环境变量: VITE_API_BASE_URL
3. 输出构建命令和输出目录

预期vercel.json:

{
  "rewrites": [{ "source": "/(.*)", "destination": "/index.html" }],
  "buildCommand": "pnpm build",
  "outputDirectory": "dist",
  "env": {
    "VITE_API_BASE_URL": "@api-base-url"
  }
}

实战案例:Task Dashboard完整项目

项目概览

下面是一个完整的任务管理仪表盘项目,综合运用前面七步的所有技术。整体架构如下:

graph TB
    subgraph Browser["浏览器"]
        subgraph Router["React Router v7"]
            RP[RouterProvider] --> Dash[DashboardPage]
            RP --> TL[TaskListPage]
            RP --> TD[TaskDetailPage]
            RP --> TF[TaskFormPage]
            RP --> Set[SettingsPage]
        end

        subgraph State["状态管理"]
            RQ[TanStack Query<br/>服务端状态] --> Cache[缓存层]
            ZS[Zustand<br/>客户端状态] --> UI[UI状态]
        end

        subgraph Components["组件层"]
            UI_Comps[原子组件<br/>Button/Input/Badge] --> Feat_Comps[业务组件<br/>TaskCard/TaskList]
            Feat_Comps --> Pages[页面组件]
        end
    end

    subgraph Server["后端API"]
        API["/api/tasks<br/>CRUD Endpoints"]
    end

    Pages --> State
    State --> Services[API Service层]
    Services -->|fetch| Server

核心文件清单

文件路径 作用 行数估计
CLAUDE.md 项目约定 ~60行
src/types/task.ts Task类型定义 ~20行
src/services/api.ts HTTP客户端封装 ~80行
src/services/taskService.ts Task API调用 ~50行
src/hooks/useTaskQueries.ts TanStack Query hooks ~100行
src/stores/uiStore.ts UI状态管理 ~60行
src/components/ui/*.tsx 基础组件(5个) ~400行
src/components/layout/*.tsx 布局组件(3个) ~200行
src/components/features/*.tsx 业务组件(6个) ~500行
src/pages/*.tsx 页面组件(5个) ~600行
src/router.tsx 路由配置 ~30行
总计 ~2100行

完整开发Prompt序列

按以下顺序向Claude Code发出指令,可以高效完成整个项目:

# Step 1 — 基础设施(5分钟)
"初始化项目,安装所有依赖,配置Tailwind、Vitest、路径别名"

# Step 2 — 类型与API层(10分钟)
"创建所有TypeScript类型定义和API Service层"

# Step 3 — 状态管理(10分钟)
"创建TanStack Query hooks和Zustand store"

# Step 4 — UI组件库(15分钟)
"生成所有原子组件,每个组件带完整测试"

# Step 5 — 布局组件(10分钟)
"生成Layout、Header、Sidebar布局组件"

# Step 6 — 业务组件(15分钟)
"生成TaskCard、TaskList、TaskForm、StatusFilter等业务组件"

# Step 7 — 页面组件(15分钟)
"生成所有页面组件并配置路由"

# Step 8 — 测试与优化(10分钟)
"运行全量测试,修复失败用例,分析构建产物大小"

总估计:约90分钟完成一个完整的前端项目。

性能基准

完成后的项目应达到以下指标:

指标 目标值
首屏LCP < 1.5s
FID < 100ms
CLS < 0.1
构建产物总大小 < 200KB (gzip)
测试覆盖率 > 80%
TypeScript错误 0
ESLint警告 0

进阶技巧:让Claude Code更好地服务前端开发

技巧一:利用shadcn/ui Skill加速组件开发

安装shadcn/ui的Claude Code Skill后,可以直接用自然语言生成高质量的shadcn组件:

# 安装shadcn CLI
pnpm dlx shadcn@latest init

# 在Claude Code中使用
"用shadcn/ui的DataTable组件实现任务列表,支持排序、筛选和分页"

技巧二:Figma设计稿到代码

如果团队使用Figma,可以通过Figma MCP Server将设计稿直接转化为代码:

1. 安装Figma MCP Server
2. 在Claude Code中输入: "根据Figma文件 xxx 的设计稿,生成TaskCard组件"
3. Claude Code会读取Figma的设计令牌、布局和样式,生成匹配的React组件

技巧三:渐进式迁移现有项目

对于已有的React项目,不要一次性重构。使用Claude Code的渐进式策略:

第一阶段: 只添加CLAUDE.md,让Claude Code理解项目现状
第二阶段: 让Claude Code为新功能编写代码(遵循现有模式)
第三阶段: 逐步让Claude Code重构旧代码(一次一个模块)
第四阶段: 引入新的工具链(Tailwind、Zustand等)

技巧四:组件文档自动生成

为 src/components/ui/ 下所有组件生成 Storybook stories 文件。
每个组件至少3个story: Default, WithVariants, EdgeCase。
使用CSF 3.0格式。

常见陷阱与规避策略

陷阱1:过度依赖Claude Code生成复杂交互

Claude Code擅长生成结构化代码,但对于复杂的拖拽、手势、动画交互,建议先写好交互逻辑的伪代码注释,再让Claude Code填充实现。

陷阱2:忽略可访问性

在CLAUDE.md中强制要求可访问性规范:

## Accessibility (Must Follow)
- 所有交互元素必须有aria-label
- 表单input必须关联label
- 颜色对比度至少4.5:1
- 键盘可操作(Tab/Enter/Escape)
- 使用role属性标注自定义组件

陷阱3:生成代码与团队规范不一致

把团队的ESLint配置、Prettier配置、Git hooks都配置好后再使用Claude Code。这样Claude Code生成的代码会自动遵循团队规范。

完整工作流总览

flowchart LR
    A[编写CLAUDE.md] --> B[项目初始化<br/>安装依赖]
    B --> C[类型定义<br/>API层]
    C --> D[状态管理<br/>Query+Store]
    D --> E[UI组件库<br/>原子组件]
    E --> F[布局+路由<br/>页面骨架]
    F --> G[业务组件<br/>功能页面]
    G --> H[测试+修复<br/>构建优化]
    H --> I[部署上线]

    style A fill:#2563EB,color:#fff
    style I fill:#22C55E,color:#fff

延伸阅读

训练营适用性评估

评估维度 说明
适合训练营类型 前端工程师集训营、全栈开发训练营、AI辅助编程工作坊
学员基础要求 6个月以上React经验,了解TypeScript基础
预计教学时长 4-6小时(含实操练习)
实验环境要求 每人一台开发机,安装好Claude Code和Node.js 20+
课程组织建议 上午讲解7步方法论(2h),下午实操完成Task Dashboard项目(3h),最后总结Review(1h)
课后作业 将Task Dashboard扩展为完整的项目管理工具,添加看板视图和团队协作功能

参考来源

  1. How to Use Claude Code for React Development: Components, Hooks, and Performance — Claude Code在React开发中的组件生成、Hooks编写和性能优化实践
  2. Build the Perfect CLAUDE.md for Your Next.js TS Project — 面向React+TypeScript项目的CLAUDE.md编写模板与最佳实践
  3. Claude Code for React: Build Components Faster Without Sacrificing Quality — 在保证质量的前提下使用Claude Code加速React组件开发的工作流
  4. React TypeScript Frontend Development Guide — Anthropic官方发布的React+TypeScript前端开发完整指南
  5. Using CLAUDE.md files: Customizing Claude Code for your codebase — Anthropic官方关于CLAUDE.md文件配置的详细文档

[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。

51学通信知识星球海报-扫码加入