手写一个 CLAUDE.md——从空白到最佳实践

上篇我们聊了 CLAUDE.md 的概念——它是给 AI 看的项目手册,告诉 AI 你的项目怎么跑、有什么约定。

但概念归概念,真让你写,你可能还是不知道从哪里下笔。

这篇我们用一个真实的前端项目为例,从空白开始,一步步写出一份高质量的 CLAUDE.md。

2.1 先认识我们的"项目"

假设你有一个电商后台管理系统,技术栈是:

框架:React 18 + Next.js 14 (App Router)
语言:TypeScript (strict mode)
样式:Tailwind CSS
状态管理:Zustand
API 请求:React Query + axios
测试:Vitest + Testing Library
包管理:pnpm
目录:src/ 下的标准 Next.js 结构

这是一个很常见的项目结构。没有 CLAUDE.md 的时候,你让 Claude “帮我加一个用户列表页面”,它生成的代码可能用的是 class component、CSS 文件放在 styles/ 下、API 请求直接写在组件里——完全不匹配你的项目风格。

每次你都得纠正它:“我们用函数组件”“API 放 services/ 下”“不要用 CSS 文件,用 Tailwind”。

有了 CLAUDE.md,这些只需要写一次。

2.2 第一步:项目概览

先把项目的基本信息告诉 AI。不用长篇大论,几句话说清楚就行。

# 电商后台管理系统

面向公司内部运营团队的后台系统,管理订单、商品、用户和数据报表。

为什么要写"面向公司内部"?因为 AI 可能会默认这是一个公开产品,考虑 SEO、SSR、性能优化——这些都是不必要的。让 AI 知道使用场景,它的建议会更对路。

2.3 第二步:技术栈

技术栈是 CLAUDE.md 最重要的部分之一。写清楚 AI 就不会推荐错误的技术方案。

## 技术栈

### 核心
- React 18 + Next.js 14 (App Router)
- TypeScript(strict mode,eslint 配置在项目根目录)
- Tailwind CSS

### 状态与数据
- Zustand(全局状态)
- React Query v5(服务端状态和缓存)
- axios(HTTP 客户端)
- zod(运行时类型校验)

### 测试
- Vitest + React Testing Library
- Playwright(E2E 测试)

### 工具
- pnpm(包管理,禁止使用 npm 或 yarn)
- ESLint + Prettier
- husky + lint-staged

这里有一个细节:版本号。React Query v4 和 v5 的 API 差别很大,写清楚版本号,AI 生成的代码就不会用错 API。

还有一个更重要的细节:禁止事项。“禁止使用 npm 或 yarn”——如果你不写这一句,AI 可能哪天就给你跑了个 npm install,把你的 pnpm-lock.yaml 搞乱。

2.4 第三步:开发命令

把日常命令都列出来,AI 就不用猜了。特别是那些不常用的命令——AI 记不住 pnpm vitest --coverage,但你写在 CLAUDE.md 里它就知道了。

## 开发命令

# 安装
pnpm install                    # 安装依赖(新增依赖也要用 pnpm add)
pnpm update                     # 更新依赖

# 开发
pnpm dev                        # 启动开发服务器 → http://localhost:3000
pnpm build                      # 生产构建
pnpm start                      # 启动生产服务器

# 代码质量
pnpm lint                       # ESLint 检查
pnpm lint:fix                   # ESLint 自动修复
pnpm type-check                 # TypeScript 类型检查
pnpm format                     # Prettier 格式化

# 测试
pnpm test                       # 运行单元测试
pnpm test:watch                 # 监听模式
pnpm test:coverage              # 覆盖率报告
pnpm test:e2e                   # E2E 测试

# 数据库
pnpm db:migrate                 # 运行数据库迁移
pnpm db:seed                    # 填充测试数据

你可能会觉得"这些太基础了,AI 应该知道"。但真实情况是:AI 经常猜错命令。它可能猜 npm start 但实际上项目用的是 pnpm dev。也可能会漏掉 type-check 这个重要步骤。

每一条命令都是给 AI 省一次猜测。

2.5 第四步:编码规范

这是最有价值的部分,也是拉开差距的地方。

## 编码规范

### 组件
- 使用函数组件 + Hooks,禁止使用 class 组件
- 组件文件使用 PascalCase(UserProfile.tsx)
- 非组件文件使用 kebab-case(user-api.ts)
- 每个组件一个文件
- 页面组件放在 app/ 目录下,业务组件放在 components/ 下

### TypeScript
- 启用 strict mode
- 禁止使用 any,优先使用 unknown
- API 请求和响应的类型定义在 types/api.ts
- 共享类型定义在 types/ 目录下

### 样式
- 使用 Tailwind CSS 类名,禁止编写自定义 CSS 文件
- 复杂的样式使用 @apply 指令提取到组件同级文件中
- 颜色使用 Tailwind 的预设色板,不要使用十六进制颜色

### API 请求
- 所有 API 请求放在 services/ 目录下
- 每个模块一个文件(services/user.ts、services/order.ts)
- 使用 React Query 的 useQuery / useMutation
- query key 统一管理在 lib/query-keys.ts

### 状态管理
- 全局状态用 Zustand(stores/ 目录)
- 服务端状态用 React Query
- 组件内状态用 useState / useReducer
- URL 参数用 useSearchParams

### Git
- 使用 Conventional Commits 格式
- 分支命名:feature/xxx、fix/xxx、chore/xxx
- PR 标题格式:<type>(<scope>): <description>

看到区别了吗?这些不是通用的 JavaScript 规范,而是你的项目的专属规范

有些是常识(“使用函数组件”),但更多的是只有你的团队才知道的约定(“query key 统一管理在 lib/query-keys.ts”“禁止使用十六进制颜色”)。

这些约定新人来了要学一两周,写在 CLAUDE.md 里,AI 一遍就学会了。

2.6 第五步:目录结构

告诉 AI 代码放在什么地方,它就不会把组件乱放了。

## 目录结构

src/
├── app/                    # Next.js App Router
│   ├── layout.tsx          # 根布局
│   ├── page.tsx            # 首页/登录页
│   ├── dashboard/          # 仪表盘页面
│   ├── orders/             # 订单管理
│   ├── products/           # 商品管理
│   └── users/              # 用户管理
├── components/             # 共享组件
│   ├── ui/                 # 基础 UI 组件(Button、Modal、Table 等)
│   ├── layout/             # 布局组件(Sidebar、Header 等)
│   └── shared/             # 业务共享组件
├── services/               # API 请求
│   ├── http.ts             # axios 实例和拦截器
│   ├── user.ts             # 用户相关 API
│   ├── order.ts            # 订单相关 API
│   └── product.ts          # 商品相关 API
├── stores/                 # Zustand stores
├── types/                  # TypeScript 类型定义
├── lib/                    # 工具函数和配置
│   ├── query-keys.ts       # React Query key 管理
│   └── utils.ts            # 通用工具函数
├── hooks/                  # 自定义 Hooks
└── styles/                 # 全局样式(Tailwind 配置)

目录结构写清楚之后,你让 Claude “在订单管理页面加一个搜索功能”,它会直接去 src/app/orders/ 下找对应的文件,而不是在 pages/ 或者 containers/ 下面新建文件。

2.7 第六步:边界与约束

这一步很多人会忽略,但它往往是 CLAUDE.md 里最有价值的部分。

## 重要的约束

1. 不要修改 src/lib/ 下的文件,除非有明确说明
2. lib/utils.ts 中的工具函数必须有单元测试覆盖
3. 数据库 schema 的修改必须同时更新 types/ 下的类型定义
4. 不要引入新的 npm 包,除非经过技术评审
5. API 接口的字段命名使用 snake_case,前端代码使用 camelCase
6. 所有新增文件必须包含 TypeScript 类型定义

约束告诉 AI 什么不能做,这比告诉它能做什么更能避免问题。

2.8 完整的 CLAUDE.md

把前面六步拼起来,就是一份高质量的 CLAUDE.md:

# 电商后台管理系统

面向公司内部运营团队的后台系统,管理订单、商品、用户和数据报表。

## 技术栈

### 核心
- React 18 + Next.js 14 (App Router)
- TypeScript(strict mode)
- Tailwind CSS

### 状态与数据
- Zustand(全局状态)
- React Query v5(服务端状态)
- axios(HTTP 客户端)
- zod(运行时类型校验)

### 工具
- pnpm(包管理,禁止使用 npm 或 yarn)
- Vitest + React Testing Library
- Playwright(E2E 测试)
- ESLint + Prettier + husky

## 开发命令
- pnpm dev — 启动开发(端口 3000)
- pnpm build — 生产构建
- pnpm test — 运行单元测试
- pnpm test:e2e — E2E 测试
- pnpm lint — ESLint 检查
- pnpm type-check — 类型检查

## 编码规范
- 函数组件 + Hooks,禁止 class 组件
- 文件命名:组件 PascalCase,其他 kebab-case
- 禁止使用 any,优先 unknown
- 使用 Tailwind,禁止自定义 CSS 文件
- API 请求放 services/,React Query key 管理在 lib/query-keys.ts
- 全局状态用 Zustand,服务端状态用 React Query

## 目录结构
src/
├── app/           # 页面(App Router)
├── components/    # 共享组件
├── services/      # API 请求
├── stores/        # Zustand stores
├── types/         # 类型定义
├── lib/           # 工具函数
├── hooks/         # 自定义 Hooks
└── styles/        # 全局样式

## 约束
- 不要直接修改 lib/ 下的文件
- 新增依赖需经评审
- API 字段 snake_case,前端代码 camelCase
- 所有新增文件必须有类型定义

这份 CLAUDE.md 大概 500 字。占用上下文不多,但它能让 AI 生成的代码从一开始就符合你的项目标准

2.9 这些内容分别放在哪个层级?

你可能注意到了,前面的六步都是在"项目级 CLAUDE.md"的视角下写的。但根据第 1 篇,CLAUDE.md 有三个层级。那六步的内容是不是都应该放项目级?

不是。区分清楚什么放哪,才能发挥分层管理的优势。

放用户级(~/.claude/CLAUDE.md)

跟个人习惯相关、跟项目无关的内容。

# 我的个人偏好

- 代码使用双引号
- 注释用中文写
- Git commit 使用英文写
- 默认用 pnpm,没有再用 npm

什么时候用: 你有自己的一套写法习惯,但不想强迫整个团队。比如团队规范用单引号,但你个人偏好双引号——放用户级,你自己的项目生效,不影响团队。

放项目级(项目根目录/CLAUDE.md)

跟具体项目绑定的、所有团队成员都应该遵守的内容。

步骤 内容 放项目级?
第一步:项目概览 项目用途和技术栈 ✅ 必须
第二步:技术栈 框架、版本、工具 ✅ 必须
第三步:开发命令 启动、测试、构建 ✅ 必须
第四步:编码规范 团队规范 ✅ 必须
第五步:目录结构 代码组织方式 ✅ 必须
第六步:边界约束 什么不能做 ✅ 必须

这些都应该放项目级。因为它们是项目本身的属性,不随人变。

放子目录级(子目录/CLAUDE.md)

项目内特定模块或子包专用的信息。

比如你的项目根目录的 CLAUDE.md 已经写了通用规范,但 apps/admin/ 目录下的后台管理有额外的规范:

# apps/admin/CLAUDE.md

本目录是后台管理系统,跟前台应用不同:

- 使用 Ant Design 组件库(前台用 Tailwind)
- 所有页面都需要权限校验
- API 路径前缀是 /api/admin/
- 不需要考虑 SEO

什么时候用: monorepo 中的子包、大型项目中某个有特殊规范的模块。

一张表看懂

内容 放哪 原因
个人代码风格偏好 用户级 跟项目无关
项目技术栈和命令 项目级 所有人都要用
团队编码规范 项目级 统一标准
子模块特有规范 子目录级 不污染其他模块
个人工作流偏好 用户级 不影响团队

一个反例

有人把个人偏好写进项目级的 CLAUDE.md:

# 项目 CLAUDE.md

## 技术栈
- React 18
- TypeScript

## 编码规范
- 使用双引号(注:这是张三的个人偏好,其他人可以不遵守)

这就违背了 CLAUDE.md 的初衷——项目级应该写"项目规范"而不是"个人偏好"。如果张三离职了,这条注释要不要删?如果李四也用这个项目,她看到"可以不遵守"会不会困惑?

正确的做法: 张三把"使用双引号"放自己的用户级 CLAUDE.md,项目级只写团队统一认可的规范。

2.10 写完怎么测试?

CLAUDE.md 写完了,怎么知道它有没有效果?

几个简单的测试方法:

测试 1:问项目信息

这个项目用什么技术栈?
怎么启动?
测试怎么跑?

AI 应该能直接从 CLAUDE.md 中找到答案,而不是猜测。

测试 2:让它生成代码

帮我新建一个用户管理页面,列出所有用户

生成的代码应该:

  • 文件放在 src/app/users/
  • 使用函数组件
  • API 请求写在 services/user.ts
  • 使用 React Query 管理请求状态
  • 用 Tailwind 样式

如果生成的代码在这些方面有偏差,说明 CLAUDE.md 还需要补充或调整。

测试 3:检查约束

帮我安装 react-select

AI 应该提醒你"这个项目需要经过技术评审才能引入新依赖"——因为 CLAUDE.md 里写了约束。

2.10 小结

写一份好的 CLAUDE.md 只需要六步:

  1. 项目概览:这个项目是干什么的
  2. 技术栈:用什么技术、什么版本、什么禁止用
  3. 开发命令:所有常用命令,包括不常用的
  4. 编码规范:你们团队独有的约定(最有价值的部分)
  5. 目录结构:代码放在哪
  6. 约束:什么不能做

但写在哪同样重要:

  • 项目规范(技术栈、命令、编码规范)→ 项目级
  • 模块特有规范(子项目特殊规则)→ 子目录级
  • 个人偏好(代码风格、语言习惯)→ 用户级 ~/.claude/CLAUDE.md

每部分放对层级,个人偏好不干扰项目规范,项目规范不被个人偏好覆盖。

CLAUDE.md 的价值在于——你写一次,AI 每次都用。 不像你口头交代,说完了 AI 可能转头就忘。


上一篇:CLAUDE.md 是什么?——AI 协作的"项目手册"

更多推荐