项目配置最佳实践
配置做得好,Claude Code用起来顺手。配置不好,Claude老是误解你的意思,生成一堆不合规范的代码,甚至引入安全漏洞。
下面聊聊怎么配置项目,让Claude Code真正成为你的得力助手。
为什么要重视配置
配置不好的代价
没配置CLAUDE.md:
你: 创建一个用户列表组件
Claude: [创建了 UserList.js]
- 用了类组件(项目已经全面迁移函数式组件)
- 文件名驼峰命名(项目要求kebab-case)
- inline样式(项目要求CSS Modules)
- 没TypeScript 类型(项目是TS)
你: 不对不对,都不符合规范...[开始返工]
返工: 15分钟
配置完善后:
你: 创建一个用户列表组件
Claude: [创建了 user-list.tsx]
✓ 函数式组件 + TypeScript
✓ kebab-case命名
✓ CSS Modules
✓ 完整类型定义
✓ 符合项目规范
✓ 包含测试框架
一次到位,不用改
省了15分钟 + 避免错误
数据说话:
| 配置情况 | 效率提升 | 错误减少 | 一次对率 |
|---|---|---|---|
| 基础配置 | 40% | 60% | 75% |
| 完整配置 | 70% | 85% | 95% |
| 没配置 | 0% | 0% | 30% |
CLAUDE.md完整模板
企业级完整模板
这是一个适用于中大型项目的CLAUDE.md完整模板,涵盖所有关键配置项:
# 项目名称: [Your Project Name]
## 项目概述
[1-2句话描述项目的核心功能和目标]
- **项目类型**: [Web应用/移动应用/桌面应用/API服务等]
- **主要用户**: [目标用户群体]
- **核心价值**: [项目 解决的核心问题]
- **当前状态**: [开发中/生产环境/维护模式]
## 技术栈
### 核心框架
- **前端**: [框架名称] [版本]
- **后端**: [框架名称] [版本]
- **数据库**: [数据库类型] [版本]
- **运行时**: [Node.js/Python/Java等] [版本要求]
### 开发工具
- **语言**: [TypeScript/JavaScript/Python等] [版本]
- **构建工具**: [Vite/Webpack/Parcel等]
- **包管理器**: [npm/yarn/pnpm]
- **版本控制**: Git
- **CI/CD**: [GitHub Actions/GitLab CI等]
### 依赖管理
```json
// package.json关键依赖示例
{
"dependencies": {
"react": "^18.2.0",
"typescript": "^5.0.0"
}
}
项目架构
架构模式
- 设计模式: [MVC/微服务/分层架构/单体架构等]
- 目录组织: [功能模块/技术分层/混合方式]
目录结构
project-root/
├── src/ # 源代码目录
│ ├── components/ # [说明]
│ ├── pages/ # [说明]
│ ├── hooks/ # [说明]
│ ├── utils/ # [说明]
│ ├── services/ # [说明]
│ └── types/ # [说明]
├── tests/ # 测试目录
├── docs/ # 文档目录
├── config/ # 配置文件
└── scripts/ # 构建和部署脚本
模块划分
- 模块A: [职责和边界]
- 模块B: [职责和边界]
- 共享模块: [哪些是共享的]
编码规范
命名约定
文件命名
- 组件文件:
PascalCase.tsx(如UserProfile.tsx) - 工具文件:
kebab-case.ts(如format-date.ts) - 样式文件:
*.module.css(如UserProfile.module.css) - 测试文件:
*.test.ts(如utils.test.ts)
代码命名
// 类和接口: PascalCase
class UserService {}
interface UserProfile {}
// 函数和变量: camelCase
function getUserData() {}
const userName = 'John';
// 常量: UPPER_SNAKE_CASE
const MAX_RETRY_COUNT = 3;
// 私有成员: _prefix
private _internalState = {};
// TypeScript类型: PascalCase + Type/Interface后缀
type UserType = {};
interface UserConfig {}
代码风格
TypeScript配置
- 严格模式: 必须启用
strict: true - 类型标注: 所有函数必须有返回类型
- 禁止使用:
any类型(使用unknown代替) - Null处理: 启用
strictNullChecks
代码格式
// 1. 导入顺序
// 1.1 React/框架核心
import { useState, useEffect } from 'react';
// 1.2 第三方库
import axios from 'axios';
import clsx from 'clsx';
// 1.3 内部模块(使用路径别名)
import { Button } from '@/components/atoms';
import { useAuth } from '@/hooks';
// 1.4 类型导入
import type { User } from '@/types';
// 1.5 样式文件
import styles from './UserProfile.module.css';
// 2. 组件定义
export function UserProfile({ userId }: UserProfileProps) {
// 2.1 Hooks(按顺序: state -> effect -> context -> custom)
const [user, setUser] = useState<User | null>(null);
useEffect(() => {
// effect logic
}, [userId]);
// 2.2 派生状态
const isAdmin = user?.role === 'admin';
// 2.3 事件处理函数
const handleSave = () => {
// logic
};
// 2.4 渲染
return (
<div className={styles.container}>
{/* JSX */}
</div>
);
}
ESLint规则
{
"rules": {
"no-console": "warn",
"no-debugger": "error",
"prefer-const": "error",
"no-var": "error",
"@typescript-eslint/no-explicit-any": "error",
"@typescript-eslint/explicit-function-return-type": "warn"
}
}
注释规范
/**
* 用户服务类
* 负责用户相关的业务逻辑和数据操作
*/
export class UserService {
/**
* 根据用户ID获取用户信息
* @param userId - 用户ID,必须是有效的UUID格式
* @returns 返回用户对象,如果用户不存在则返回null
* @throws {InvalidUserIdError} 当userId格式无效时抛出
* @example
* ```typescript
* const user = await userService.getById('123e4567-e89b-12d3-a456-426614174000');
* ```
*/
async getById(userId: string): Promise<User | null> {
// 实现逻辑
}
}
开发工作流
常用命令
开发命令
# 安装依赖
npm install
# 启动开发服务器
npm run dev # http://localhost:3000
# 构建生产版本
npm run build
# 本地预览生产构建
npm run preview
# 代码检查
npm run lint # ESLint检查
npm run format # Prettier格式化
npm run type-check # TypeScript类型检查
测试命令
# 运行所有测试
npm test
# 运行测试并生成覆盖率报告
npm run test:coverage
# 监听模式(开发时使用)
npm run test:watch
# 运行E2E测试
npm run test:e2e
数据库命令
# 数据库迁移
npm run db:migrate # 执行迁移
npm run db:rollback # 回滚迁移
npm run db:seed # 填充种子数据
# 数据库客户端
npm run db:studio # 打开数据库管理界面
Git命令
# 提交前检查
npm run prepare # Husky钩子,自动运行lint和test
# 代码提交(使用Commitlint)
git commit # 交互式提交,遵循约定式提交规范
分支策略
main # 生产分支,受保护
├── develop # 开发分支
├── feature/* # 功能分支
├── bugfix/* # 修复分支
└── hotfix/* # 紧急修复分支
分支命名规范:
- 功能开发:
feature/feature-name - Bug修复:
bugfix/bug-description - 紧急修复:
hotfix/critical-fix - 重构:
refactor/component-name - 文档:
docs/document-name
提交规范
遵循约定式提交:
<type>(<scope>): <subject>
<body>
<footer>
Type类型:
feat: 新功能fix: Bug修复docs: 文档更新style: 代码格式(不影响代码运行)refactor: 重构perf: 性能优化test: 测试相关chore: 构建/工具链相关
示例:
feat(auth): add OAuth2 login with Google
Implement OAuth2 authentication flow:
- Add Google OAuth provider
- Implement token refresh mechanism
- Add user profile synchronization
Closes #123
环境配置
环境变量
必需变量
# .env.example (提交到Git)
# 应用配置
NODE_ENV=development
PORT=3000
APP_URL=http://localhost:3000
# 数据库
DATABASE_URL=postgresql://user:password@localhost:5432/dbname
REDIS_URL=redis://localhost:6379
# API密钥
API_SECRET_KEY=your-secret-key-here
JWT_SECRET=your-jwt-secret
JWT_EXPIRES_IN=15m
# 第三方服务
STRIPE_API_KEY=sk_test_xxx
AWS_ACCESS_KEY_ID=your-access-key
AWS_SECRET_ACCESS_KEY=your-secret-key
# 开发工具
DEBUG=true
LOG_LEVEL=debug
环境配置
// config/env.ts
export const config = {
port: parseInt(process.env.PORT || '3000', 10),
nodeEnv: process.env.NODE_ENV || 'development',
database: {
url: process.env.DATABASE_URL!,
},
jwt: {
secret: process.env.JWT_SECRET!,
expiresIn: process.env.JWT_EXPIRES_IN || '15m',
},
isDevelopment: process.env.NODE_ENV !== 'production',
isProduction: process.env.NODE_ENV === 'production',
} as const;
// 运行时验证
if (!config.database.url) {
throw new Error('DATABASE_URL environment variable is required');
}
多环境管理
env/
├── .env.example # 模板(提交)
├── .env.development # 开发环境(本地,不提交)
├── .env.staging # 预发布环境(部署时注入)
└── .env.production # 生产环境(部署时注入)
Git忽略配置:
# .gitignore
.env
.env.local
.env.*.local
*.env
API设计规范
RESTful API约定
GET /api/v1/resources # 列表
GET /api/v1/resources/:id # 详情
POST /api/v1/resources # 创建
PUT /api/v1/resources/:id # 完整更新
PATCH /api/v1/resources/:id # 部分更新
DELETE /api/v1/resources/:id # 删除
响应格式
成功响应:
{
"success": true,
"data": {
"id": "123",
"name": "Resource Name"
},
"message": "操作成功",
"meta": {
"timestamp": "2025-01-15T10:30:00Z",
"version": "1.0.0"
}
}
错误响应:
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "请求参数验证失败",
"details": [
{
"field": "email",
"message": "邮箱格式不正确"
}
]
},
"meta": {
"timestamp": "2025-01-15T10:30:00Z",
"requestId": "req_abc123"
}
}
API版本控制
// 通过URL路径版本化
// api/v1/users
// api/v2/users
// 或通过Header版本化
// Accept: application/vnd.api+json; version=1
测试策略
测试金字塔
/\
/ \ E2E测试 (10%)
/____\ - 关键用户流程
/ \ - 使用Playwright/Cypress
/ \ - 集成测试 (30%)
/ \ - API测试
/____________\ - 组件集成
/ \ - 单元测试 (60% - 优先)
/ \ - 函数/类/组件单元测试
测试规范
// 单元测试示例
describe('UserService', () => {
describe('getById', () => {
it('should return user when valid id is provided', async () => {
// Arrange
const userId = '123';
const expectedUser = { id: userId, name: 'John' };
jest.spyOn(userRepository, 'findById').mockResolvedValue(expectedUser);
// Act
const result = await userService.getById(userId);
// Assert
expect(result).toEqual(expectedUser);
});
it('should return null when user not found', async () => {
// Arrange
const userId = '999';
jest.spyOn(userRepository, 'findById').mockResolvedValue(null);
// Act
const result = await userService.getById(userId);
// Assert
expect(result).toBeNull();
});
});
});
测试覆盖率要求
- 整体覆盖率: >= 80%
- 核心业务逻辑: >= 90%
- 工具函数: 100%
- 组件测试: >= 70%
安全规范
认证和授权
// JWT认证中间件
export async function authMiddleware(req: Request, res: Response, next: NextFunction) {
const token = req.headers.authorization?.replace('Bearer ', '');
if (!token) {
return res.status(401).json({
success: false,
error: { code: 'UNAUTHORIZED', message: '缺少认证令牌' }
});
}
try {
const decoded = jwt.verify(token, config.jwt.secret);
req.user = decoded;
next();
} catch (error) {
return res.status(401).json({
success: false,
error: { code: 'INVALID_TOKEN', message: '令牌无效或已过期' }
});
}
}
数据验证
import { z } from 'zod';
// 请求验证schema
export const CreateUserSchema = z.object({
email: z.string().email('邮箱格式不正确'),
password: z.string().min(8, '密码至少8位'),
name: z.string().min(2, '姓名至少2个字符'),
age: z.number().min(18, '必须年满18岁').optional(),
});
// 在Controller中使用
export async function createUser(req: Request, res: Response) {
try {
const validatedData = CreateUserSchema.parse(req.body);
// 处理逻辑
} catch (error) {
if (error instanceof z.ZodError) {
return res.status(400).json({
success: false,
error: {
code: 'VALIDATION_ERROR',
message: '请求参数验证失败',
details: error.errors
}
});
}
}
}
安全清单
- ✅ 所有用户输入必须验证
- ✅ 敏感数据必须加密存储(密码使用bcrypt,成本因子>=10)
- ✅ 使用参数化查询,防止SQL注入
- ✅ 实施CORS策略
- ✅ 设置安全HTTP头(使用helmet.js)
- ✅ 实施速率限制(rate limiting)
- ✅ 生产环境禁用错误堆栈输出
- ✅ 定期更 新依赖,修复安全漏洞
- ✅ 使用HTTPS(生产环境)
- ✅ 实施内容安全策略(CSP)
性能优化
前端性能
// 1. 代码分割
import { lazy, Suspense } from 'react';
const UserProfile = lazy(() => import('./UserProfile'));
function App() {
return (
<Suspense fallback={<Loading />}>
<UserProfile />
</Suspense>
);
}
// 2. 图片优化
import Image from 'next/image';
<Image
src="/avatar.jpg"
alt="用户头像"
width={100}
height={100}
loading="lazy"
/>
// 3. 防抖和节流
import { debounce } from 'lodash';
const handleSearch = debounce((query: string) => {
// 搜索逻辑
}, 300);
后端性能
// 1. 数据库查询优化
// ❌ 不好:N+1查询
const users = await User.findAll();
for (const user of users) {
user.posts = await Post.findAll({ where: { userId: user.id } });
}
// ✅ 好:预加载关联数据
const users = await User.findAll({
include: [{ model: Post, as: 'posts' }]
});
// 2. 缓存策略
import Redis from 'ioredis';
const redis = new Redis();
export async function getUserById(userId: string) {
const cacheKey = `user:${userId}`;
// 先查缓存
const cached = await redis.get(cacheKey);
if (cached) return JSON.parse(cached);
// 查数据库
const user = await User.findById(userId);
// 写入缓存(5分钟过期)
await redis.setex(cacheKey, 300, JSON.stringify(user));
return user;
}
错误处理
错误分类
// 自定义错误类
export class AppError extends Error {
constructor(
public statusCode: number,
public code: string,
message: string,
public isOperational = true
) {
super(message);
this.name = this.constructor.name;
Error.captureStackTrace(this, this.constructor);
}
}
export class ValidationError extends AppError {
constructor(message: string) {
super(400, 'VALIDATION_ERROR', message);
}
}
export class NotFoundError extends AppError {
constructor(resource: string) {
super(404, 'NOT_FOUND', `${resource}不存在`);
}
}
// 全局错误处理中间件
export function errorHandler(
err: Error,
req: Request,
res: ExpressResponse,
next: NextFunction
) {
if (err instanceof AppError) {
return res.status(err.statusCode).json({
success: false,
error: {
code: err.code,
message: err.message
}
});
}
// 未知错误
console.error('Unexpected error:', err);
return res.status(500).json({
success: false,
error: {
code: 'INTERNAL_ERROR',
message: '服务器内部错误'
}
});
}
日志规范
import winston from 'winston';
export const logger = winston.createLogger({
level: process.env.LOG_LEVEL || 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.errors({ stack: true }),
winston.format.json()
),
transports: [
new winston.transports.File({ filename: 'error.log', level: 'error' }),
new winston.transports.File({ filename: 'combined.log' })
]
});
if (process.env.NODE_ENV !== 'production') {
logger.add(new winston.transports.Console({
format: winston.format.simple()
}));
}
// 使用示例
logger.info('User logged in', { userId: user.id, ip: req.ip });
logger.error('Database connection failed', { error: err.message });
logger.warn('High memory usage', { usage: '90%' });
Git配置最佳实践
.gitignore规范
# ============ 依赖 ============
node_modules/
.pnp
.pnp.js
# ============ 构建输出 ============
dist/
build/
out/
.next/
# ============ 环境变量 ============
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
# ============ 日志 ============
logs/
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# ============ 测试覆盖率 ============
coverage/
.nyc_output/
# ============ IDE和编辑器 ============
.vscode/
.idea/
*.swp
*.swo
*~
.DS_Store
# ============ 临时文件 ============
*.tmp
.cache/
.temp/
# ============ 操作系统 ============
Thumbs.db
.DS_Store
# ============ 数据库 ============
*.sqlite
*.db
# ============ 其他 ============
debug.log
Git Hooks配置
// package.json
{
"husky": {
"hooks": {
"pre-commit": "lint-staged",
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS",
"pre-push": "npm test"
}
},
"lint-staged": {
"*.{ts,tsx}": [
"eslint --fix",
"prettier --write",
"git add"
],
"*.{json,md}": [
"prettier --write",
"git add"
]
}
}
文档规范
代码文档
/**
* 用户管理服务
*
* @module UserService
* @description 提供用户CRUD操作、认证、权限管理等核心功能
*
* @example
* ```typescript
* import { UserService } from '@/services/UserService';
*
* const userService = new UserService();
* const user = await userService.createUser({
* email: 'user@example.com',
* password: 'securepass123'
* });
* ```
*/
export class UserService {
/**
* 创建新用户
*
* @param {CreateUserDto} data - 用户数据
* @param {string} data.email - 用户邮箱(必须唯一)
* @param {string} data.password - 用户密码(将被加密存储)
* @param {string} data.name - 用户姓名
* @returns {Promise<User>} 创建的用户对象
* @throws {DuplicateEmailError} 当邮箱已存在时抛出
* @throws {ValidationError} 当数据验证失败时抛出
*
* @example
* ```typescript
* const user = await userService.createUser({
* email: 'john@example.com',
* password: 'MySecurePass123!',
* name: 'John Doe'
* });
* ```
*/
async createUser(data: CreateUserDto): Promise<User> {
// 实现
}
}
README规范
# 项目名称
简短描述项目的主要功能和价值(一句话)
## 功能特性
- ✅ 功能点1
- ✅ 功能点2
- ✅ 功能点3
## 技术栈
- **框架**: [框架名称]
- **语言**: [语言]
- **数据库**: [数据库]
- **部署**: [部署平台]
## 快速开始
### 环境要求
- Node.js >= 16.14.0
- npm >= 8.0.0
### 安装
\`\`\`bash
git clone https://github.com/user/repo.git
cd repo
npm install
\`\`\`
### 运行
\`\`\`bash
# 开发模式
npm run dev
# 生产构建
npm run build
npm start
\`\`\`
## 项目结构
\`\`\`
src/
├── components/ # React组件
├── pages/ # 页面组件
└── utils/ # 工具函数
\`\`\`
## 贡献指南
欢迎贡献!请查看 [CONTRIBUTING.md](CONTRIBUTING.md)
## 许可证
MIT
禁止事项清单
代码层面
## ⚠️ 绝对禁止事项
### TypeScript相关
❌ **不要使用 `any` 类型**
```typescript
// ❌ 错误
function processData(data: any) { }
// ✅ 正确
function processData(data: unknown) { }
❌ 不要使用 as 强制类型断言(除非必要)
// ❌ 错误
const user = data as User;
// ✅ 正确
const user = isUser(data) ? data : null;
React相关
❌ 不要在JSX中使用匿名函数
// ❌ 错误(每次渲染都创建新函数)
<button onClick={() => handleClick(id)}>
// ✅ 正确
<button onClick={handleClick}>
❌ 不要直接修改state
// ❌ 错误
state.items.push(newItem);
setState(state);
// ✅ 正确
setState(prev => ({
...prev,
items: [...prev.items, newItem]
}));
安全相关
❌ 不要在代码中硬编码密钥
// ❌ 错误
const apiKey = 'sk_live_1234567890abcdef';
// ✅ 正确
const apiKey = process.env.API_KEY;
❌ 不要在生产环境输出错误堆栈
// ❌ 错误
res.send(err.stack);
// ✅ 正确
res.send('Internal Server Error');
性能相关
❌ 不要在渲染中执行昂贵计算
// ❌ 错误
function ExpensiveComponent() {
const result = heavyComputation(data); // 每次渲染都计算
return <div>{result}</div>;
}
// ✅ 正确
function ExpensiveComponent() {
const result = useMemo(() => heavyComputation(data), [data]);
return <div>{result}</div>;
}