手写一个 CLAUDE.md——从空白到最佳实践
手写一个 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 只需要六步:
- 项目概览:这个项目是干什么的
- 技术栈:用什么技术、什么版本、什么禁止用
- 开发命令:所有常用命令,包括不常用的
- 编码规范:你们团队独有的约定(最有价值的部分)
- 目录结构:代码放在哪
- 约束:什么不能做
但写在哪同样重要:
- 项目规范(技术栈、命令、编码规范)→ 项目级
- 模块特有规范(子项目特殊规则)→ 子目录级
- 个人偏好(代码风格、语言习惯)→ 用户级 ~/.claude/CLAUDE.md
每部分放对层级,个人偏好不干扰项目规范,项目规范不被个人偏好覆盖。
CLAUDE.md 的价值在于——你写一次,AI 每次都用。 不像你口头交代,说完了 AI 可能转头就忘。
更多推荐


所有评论(0)