<!-- title: 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已就绪：

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

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

### 1.1 创建项目

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

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

### 1.2 编写项目级CLAUDE.md

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

```markdown
# 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中执行：

```bash
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约定，输出类似：

```typescript
// 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（复合组件）
```

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

```bash
pnpm test src/components/ui/
```

### 常见问题

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

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

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

### 3.1 双层状态架构

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

```mermaid
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工厂模式：

```typescript
// 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：

```typescript
// 错误：订阅整个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 预期路由配置

```typescript
// 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配置，预期输出：

```css
/* 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生成一致的响应式代码：

```markdown
## 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 预期测试输出

```typescript
// 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 运行全量测试

```bash
pnpm test
```

如果测试失败，让Claude Code自动修复：

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

### 常见问题

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

```typescript
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：

```typescript
// 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：

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

## 实战案例：Task Dashboard完整项目

### 项目概览

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

```mermaid
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组件：

```bash
# 安装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中强制要求可访问性规范：

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

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

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

## 完整工作流总览

```mermaid
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
```

## 延伸阅读

- [Anthropic官方CLAUDE.md配置指南](https://claude.com/blog/using-claude-md-files) — 项目级CLAUDE.md编写最佳实践
- [React + TypeScript项目CLAUDE.md模板](https://www.pravin.solutions/posts/how-to-write-claude-md-react-typescript-app) — Next.js+React+TS项目的CLAUDE.md完整示例
- [Claude Code前端开发工作流](https://getbeam.dev/blog/claude-code-react-development.html) — React组件、Hooks和性能优化实战
- [TanStack Query v5官方文档](https://tanstack.com/query/latest) — 服务端状态管理完整API参考
- [Tailwind CSS v4迁移指南](https://tailwindcss.com/docs/upgrade-guide) — 从v3到v4的升级注意事项

## 训练营适用性评估

| 评估维度 | 说明 |
|----------|------|
| 适合训练营类型 | 前端工程师集训营、全栈开发训练营、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](https://getbeam.dev/blog/claude-code-react-development.html) — Claude Code在React开发中的组件生成、Hooks编写和性能优化实践
2. [Build the Perfect CLAUDE.md for Your Next.js TS Project](https://www.pravin.solutions/posts/how-to-write-claude-md-react-typescript-app) — 面向React+TypeScript项目的CLAUDE.md编写模板与最佳实践
3. [Claude Code for React: Build Components Faster Without Sacrificing Quality](https://www.visimade.com/p/analystdev-blog?article=claude-code-for-react-build-components-faster-without-sacrificing-quality) — 在保证质量的前提下使用Claude Code加速React组件开发的工作流
4. [React TypeScript Frontend Development Guide](https://claude.ai/public/artifacts/25da58a3-008d-4676-989d-60d2ebaa8503) — Anthropic官方发布的React+TypeScript前端开发完整指南
5. [Using CLAUDE.md files: Customizing Claude Code for your codebase](https://claude.com/blog/using-claude-md-files) — 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学通信知识星球海报-扫码加入](https://wiki.500nian.com/images/zhixingqiu_qrcode.png)
