Claude Code Plugins

Community-maintained marketplace

Feedback

自动代码审查,检查代码质量、性能和安全问题

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name Code Review
description 自动代码审查,检查代码质量、性能和安全问题
tags code-quality, review, best-practices

Code Review Skill

自动执行代码审查,确保代码质量。

何时使用

在以下情况自动激活代码审查:

  • 完成功能开发后
  • 创建 Pull Request 前
  • 重构代码后
  • 发现 Bug 修复后
  • 用户要求代码审查时

审查检查清单

1. 代码结构和组织

✅ 良好实践

  • 单一职责原则:每个函数/组件只做一件事
  • 文件大小合理:< 500 行(建议 < 300 行)
  • 逻辑分层清晰:UI / 业务逻辑 / 数据访问
  • 代码复用:提取重复逻辑为函数/组件

❌ 需要改进

  • 巨型组件(> 500 行)
  • 深层嵌套(> 3 层)
  • 重复代码
  • 混乱的导入顺序

2. TypeScript 类型安全

✅ 良好实践

// 明确的类型定义
interface StudentProps {
  student: Student;
  onEdit: (id: string) => void;
}

// 使用类型守卫
function isStudent(obj: unknown): obj is Student {
  return typeof obj === 'object' && obj !== null && 'id' in obj;
}

// 泛型使用
function fetchData<T>(url: string): Promise<T> {
  // ...
}

❌ 需要改进

// 避免 any
const data: any = fetchData();

// 避免类型断言滥用
const student = data as Student;

// 避免隐式 any
function process(value) {  // 应该标注类型
  // ...
}

3. React 最佳实践

✅ 良好实践

// 使用 React.FC 和 Props interface
const Component: React.FC<Props> = ({ prop1, prop2 }) => {
  // ...
};

// 合理使用 hooks
const [state, setState] = useState(initialValue);
const memoizedValue = useMemo(() => computeExpensive(a, b), [a, b]);

// 条件渲染清晰
{isLoading ? <Loader /> : <Content />}

// 事件处理器命名统一
const handleClick = () => {};
const handleSubmit = () => {};

❌ 需要改进

// 避免在渲染中定义函数
<Button onClick={() => {
  // 大量逻辑...应该提取到外部
}} />

// 避免过度使用 useEffect
useEffect(() => {
  // 应该使用更合适的 hook 或放在事件处理器中
}, [dep1, dep2, dep3, dep4]);

// 避免条件 hooks
if (condition) {
  useState(value);  // 违反 hooks 规则
}

4. 性能优化

✅ 良好实践

// 大列表使用 memo
const StudentItem = React.memo(({ student }) => {
  // ...
});

// 昂贵计算使用 useMemo
const sortedStudents = useMemo(() =>
  students.sort((a, b) => a.score - b.score),
  [students]
);

// 回调函数使用 useCallback
const handleDelete = useCallback((id: string) => {
  // ...
}, []);

❌ 需要改进

// 避免每次渲染都创建新对象
<Component style={{ margin: 10 }} />  // 应该提取到变量

// 避免在渲染中执行昂贵计算
{students.sort(...).filter(...).map(...)}  // 应该使用 useMemo

// 避免不必要的重渲染
// 缺少 React.memo 或 useMemo

5. 安全性

✅ 良好实践

// 输入验证
const isValidEmail = (email: string) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);

// XSS 防护(React 默认转义)
<div>{userInput}</div>  // 安全

// SQL 注入防护(使用参数化查询)
supabase.from('students').select('*').eq('id', userId);  // 安全

// 敏感信息不硬编码
const apiKey = process.env.VITE_API_KEY;

❌ 需要改进

// 避免 dangerouslySetInnerHTML
<div dangerouslySetInnerHTML={{ __html: userInput }} />  // 危险!

// 避免硬编码敏感信息
const apiKey = 'sk-1234567890';  // 不安全!

// 避免直接拼接 SQL(虽然 Supabase 已处理)
const query = `SELECT * FROM users WHERE id = ${userId}`;  // 危险模式

6. 错误处理

✅ 良好实践

// 完整的错误处理
try {
  const data = await fetchData();
  setData(data);
} catch (error) {
  console.error('Failed to fetch data:', error);
  toast.error('加载失败,请重试');
  setError(error instanceof Error ? error.message : '未知错误');
}

// 边界情况处理
if (!data || data.length === 0) {
  return <EmptyState />;
}

// 加载状态
{isLoading && <Loader />}
{error && <ErrorMessage error={error} />}

❌ 需要改进

// 避免忽略错误
try {
  await riskyOperation();
} catch (e) {
  // 空的 catch - 错误被静默吞没
}

// 避免不处理 Promise 拒绝
fetchData();  // 应该 await 或 .catch()

// 避免缺少边界检查
data.map(item => item.name);  // data 可能为 undefined

7. 可访问性 (a11y)

✅ 良好实践

// 语义化 HTML
<button onClick={handleClick}>提交</button>
<nav><a href="/home">首页</a></nav>

// ARIA 属性
<DialogTitle>标题</DialogTitle>
<DialogDescription>描述</DialogDescription>

// 键盘导航
<Button tabIndex={0} onKeyDown={handleKeyDown}>

❌ 需要改进

// 避免用 div 代替 button
<div onClick={handleClick}>提交</div>  // 应该用 <button>

// 避免缺少替代文本
<img src="photo.jpg" />  // 应该有 alt 属性

// 避免缺少 ARIA 标签
<DialogContent>  // 缺少 DialogTitle

8. 样式和 UI

✅ 良好实践

// 使用 Tailwind + cn 工具
import { cn } from "@/lib/utils";

<div className={cn(
  "base-classes",
  condition && "conditional-classes",
  className
)}>

❌ 需要改进

// 避免内联样式(特殊情况除外)
<div style={{ color: 'red', fontSize: 14 }}>

// 避免魔法数字
<div className="w-[237px]">  // 应该使用语义化的值

// 避免不统一的颜色
<div className="bg-green-500">  // 应该使用 #B9FF66

9. 数据库查询

✅ 良好实践

// 使用 Supabase MCP 工具
await mcp__supabase__execute_sql({
  project_id: 'giluhqotfjpmofowvogn',
  query: 'SELECT * FROM students WHERE class_id = $1',
});

// 启用 RLS
ALTER TABLE students ENABLE ROW LEVEL SECURITY;

// 合理的索引
CREATE INDEX idx_students_class ON students(class_id);

❌ 需要改进

// 避免 N+1 查询
for (const student of students) {
  const grades = await getGrades(student.id);  // 应该批量查询
}

// 避免查询所有字段
.select('*')  // 只选择需要的字段

// 避免缺少 RLS 策略
// 没有 CREATE POLICY 的表

10. 测试覆盖

✅ 良好实践

// 单元测试
describe('StudentCard', () => {
  it('renders student name', () => {
    // ...
  });
});

// 边界测试
it('handles empty data', () => {
  render(<Component data={[]} />);
  // ...
});

审查流程

1. 自动检查

# 类型检查
npm run typecheck

# 代码检查
npm run lint

# 格式检查
npm run format:check

2. 人工审查要点

功能正确性

  • 功能按预期工作
  • 边界情况处理正确
  • 错误处理完善

代码质量

  • 代码清晰易读
  • 命名语义化
  • 注释适当
  • 无冗余代码

性能

  • 无不必要的重渲染
  • 大数据集处理优化
  • API 调用次数合理

安全性

  • 输入验证
  • 权限检查
  • 敏感信息保护

可维护性

  • 代码结构清晰
  • 易于测试
  • 易于扩展

常见问题修复模式

问题:组件过大

// 之前:1000+ 行的巨型组件
const ExamManagement = () => {
  // 所有逻辑...
};

// 之后:拆分为多个小组件
const ExamManagement = () => {
  return (
    <>
      <ExamList />
      <ExamFilters />
      <ExamActions />
    </>
  );
};

问题:重复代码

// 之前:重复的按钮样式
<Button className="border-2 border-black shadow-[2px_2px_0px_0px_#000] ...">
<Button className="border-2 border-black shadow-[2px_2px_0px_0px_#000] ...">

// 之后:提取为常量
const BUTTON_STYLE = "border-2 border-black shadow-[2px_2px_0px_0px_#000] ...";
<Button className={BUTTON_STYLE}>

问题:缺少类型

// 之前
const data = await fetch('/api/students');

// 之后
const data: Student[] = await fetch('/api/students');

输出格式

审查完成后,输出以下格式的报告:

## 代码审查报告

### ✅ 优点
- 使用了 TypeScript 类型定义
- 组件结构清晰
- 错误处理完善

### ⚠️ 需要改进
1. **性能**: 第45行应该使用 useMemo 优化计算
2. **类型安全**: 第78行使用了 any,应该定义具体类型
3. **可访问性**: 第120行的 Dialog 缺少 DialogTitle

### 📝 建议
- 考虑拆分 ExamCard 组件(当前 300+ 行)
- 提取重复的样式类到常量
- 添加单元测试覆盖边界情况

### 📊 评分
- 代码质量: 8/10
- 性能: 7/10
- 安全性: 9/10
- 可维护性: 8/10

注意事项

  • 代码审查应该是建设性的,不是批评
  • 关注代码质量,而不是个人风格偏好
  • 提供具体的改进建议,而不只是指出问题
  • 认可好的代码实践