with one click
coding-standards
TypeScript、JavaScript、React 和 Node.js 开发的通用编码标准、最佳实践和模式。
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
TypeScript、JavaScript、React 和 Node.js 开发的通用编码标准、最佳实践和模式。
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
Node.js、Express 和 Next.js API 路由的后端架构模式、API 设计、数据库优化和服务端最佳实践。
Automatically extract reusable patterns from Claude Code sessions and save them as learned skills for future use.
React、Next.js、状态管理、性能优化和 UI 最佳实践的前端开发模式。
在添加身份验证、处理用户输入、使用密钥、创建 API 端点或实现支付/敏感功能时使用此技能。提供全面的安全检查清单和模式。
Suggests manual context compaction at logical intervals to preserve context through task phases rather than arbitrary auto-compaction.
在编写新功能、修复错误或重构代码时使用此技能。强制执行测试驱动开发,要求 80% 以上的覆盖率,包括单元测试、集成测试和 E2E 测试。
| name | coding-standards |
| description | TypeScript、JavaScript、React 和 Node.js 开发的通用编码标准、最佳实践和模式。 |
适用于所有项目的通用编码标准。
// ✅ 好的做法:描述性名称
const marketSearchQuery = 'election'
const isUserAuthenticated = true
const totalRevenue = 1000
// ❌ 坏的做法:不清晰的名称
const q = 'election'
const flag = true
const x = 1000
// ✅ 好的做法:动词-名词模式
async function fetchMarketData(marketId: string) { }
function calculateSimilarity(a: number[], b: number[]) { }
function isValidEmail(email: string): boolean { }
// ❌ 坏的做法:不清晰或仅使用名词
async function market(id: string) { }
function similarity(a, b) { }
function email(e) { }
// ✅ 始终使用展开运算符
const updatedUser = {
...user,
name: 'New Name'
}
const updatedArray = [...items, newItem]
// ❌ 永远不要直接修改
user.name = 'New Name' // 坏
items.push(newItem) // 坏
// ✅ 好的做法:全面的错误处理
async function fetchData(url: string) {
try {
const response = await fetch(url)
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`)
}
return await response.json()
} catch (error) {
console.error('Fetch failed:', error)
throw new Error('Failed to fetch data')
}
}
// ❌ 坏的做法:没有错误处理
async function fetchData(url) {
const response = await fetch(url)
return response.json()
}
// ✅ 好的做法:尽可能并行执行
const [users, markets, stats] = await Promise.all([
fetchUsers(),
fetchMarkets(),
fetchStats()
])
// ❌ 坏的做法:不必要的串行执行
const users = await fetchUsers()
const markets = await fetchMarkets()
const stats = await fetchStats()
// ✅ 好的做法:正确的类型
interface Market {
id: string
name: string
status: 'active' | 'resolved' | 'closed'
created_at: Date
}
function getMarket(id: string): Promise<Market> {
// 实现
}
// ❌ 坏的做法:使用 'any'
function getMarket(id: any): Promise<any> {
// 实现
}
// ✅ 好的做法:带类型的函数组件
interface ButtonProps {
children: React.ReactNode
onClick: () => void
disabled?: boolean
variant?: 'primary' | 'secondary'
}
export function Button({
children,
onClick,
disabled = false,
variant = 'primary'
}: ButtonProps) {
return (
<button
onClick={onClick}
disabled={disabled}
className={`btn btn-${variant}`}
>
{children}
</button>
)
}
// ❌ 坏的做法:没有类型,结构不清晰
export function Button(props) {
return <button onClick={props.onClick}>{props.children}</button>
}
// ✅ 好的做法:可复用的自定义 hook
export function useDebounce<T>(value: T, delay: number): T {
const [debouncedValue, setDebouncedValue] = useState<T>(value)
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(value)
}, delay)
return () => clearTimeout(handler)
}, [value, delay])
return debouncedValue
}
// 使用
const debouncedQuery = useDebounce(searchQuery, 500)
// ✅ 好的做法:正确的状态更新
const [count, setCount] = useState(0)
// 基于前一个状态的函数式更新
setCount(prev => prev + 1)
// ❌ 坏的做法:直接引用状态
setCount(count + 1) // 在异步场景中可能过时
// ✅ 好的做法:清晰的条件渲染
{isLoading && <Spinner />}
{error && <ErrorMessage error={error} />}
{data && <DataDisplay data={data} />}
// ❌ 坏的做法:三元地狱
{isLoading ? <Spinner /> : error ? <ErrorMessage error={error} /> : data ? <DataDisplay data={data} /> : null}
GET /api/markets # 列出所有市场
GET /api/markets/:id # 获取特定市场
POST /api/markets # 创建新市场
PUT /api/markets/:id # 更新市场(完整)
PATCH /api/markets/:id # 更新市场(部分)
DELETE /api/markets/:id # 删除市场
# 用于过滤的查询参数
GET /api/markets?status=active&limit=10&offset=0
// ✅ 好的做法:一致的响应结构
interface ApiResponse<T> {
success: boolean
data?: T
error?: string
meta?: {
total: number
page: number
limit: number
}
}
// 成功响应
return NextResponse.json({
success: true,
data: markets,
meta: { total: 100, page: 1, limit: 10 }
})
// 错误响应
return NextResponse.json({
success: false,
error: 'Invalid request'
}, { status: 400 })
import { z } from 'zod'
// ✅ 好的做法:模式验证
const CreateMarketSchema = z.object({
name: z.string().min(1).max(200),
description: z.string().min(1).max(2000),
endDate: z.string().datetime(),
categories: z.array(z.string()).min(1)
})
export async function POST(request: Request) {
const body = await request.json()
try {
const validated = CreateMarketSchema.parse(body)
// 使用验证后的数据继续
} catch (error) {
if (error instanceof z.ZodError) {
return NextResponse.json({
success: false,
error: 'Validation failed',
details: error.errors
}, { status: 400 })
}
}
}
src/
├── app/ # Next.js App Router
│ ├── api/ # API 路由
│ ├── markets/ # 市场页面
│ └── (auth)/ # 认证页面(路由组)
├── components/ # React 组件
│ ├── ui/ # 通用 UI 组件
│ ├── forms/ # 表单组件
│ └── layouts/ # 布局组件
├── hooks/ # 自定义 React hooks
├── lib/ # 工具函数和配置
│ ├── api/ # API 客户端
│ ├── utils/ # 辅助函数
│ └── constants/ # 常量
├── types/ # TypeScript 类型
└── styles/ # 全局样式
components/Button.tsx # 组件使用 PascalCase
hooks/useAuth.ts # hooks 使用 camelCase 并带 'use' 前缀
lib/formatDate.ts # 工具函数使用 camelCase
types/market.types.ts # 类型使用 camelCase 并带 .types 后缀
// ✅ 好的做法:解释"为什么",而不是"是什么"
// 使用指数退避以避免在故障期间压垮 API
const delay = Math.min(1000 * Math.pow(2, retryCount), 30000)
// 为了处理大型数组的性能,这里故意使用可变操作
items.push(newItem)
// ❌ 坏的做法:陈述显而易见的事实
// 计数器加 1
count++
// 将名称设置为用户的名称
name = user.name
/**
* 使用语义相似度搜索市场。
*
* @param query - 自然语言搜索查询
* @param limit - 最大结果数量(默认:10)
* @returns 按相似度分数排序的市场数组
* @throws {Error} 如果 OpenAI API 失败或 Redis 不可用
*
* @example
* ```typescript
* const results = await searchMarkets('election', 5)
* console.log(results[0].name) // "Trump vs Biden"
* ```
*/
export async function searchMarkets(
query: string,
limit: number = 10
): Promise<Market[]> {
// 实现
}
import { useMemo, useCallback } from 'react'
// ✅ 好的做法:记忆化昂贵的计算
const sortedMarkets = useMemo(() => {
return markets.sort((a, b) => b.volume - a.volume)
}, [markets])
// ✅ 好的做法:记忆化回调
const handleSearch = useCallback((query: string) => {
setSearchQuery(query)
}, [])
import { lazy, Suspense } from 'react'
// ✅ 好的做法:懒加载重型组件
const HeavyChart = lazy(() => import('./HeavyChart'))
export function Dashboard() {
return (
<Suspense fallback={<Spinner />}>
<HeavyChart />
</Suspense>
)
}
// ✅ 好的做法:仅选择需要的列
const { data } = await supabase
.from('markets')
.select('id, name, status')
.limit(10)
// ❌ 坏的做法:选择所有内容
const { data } = await supabase
.from('markets')
.select('*')
test('calculates similarity correctly', () => {
// Arrange(准备)
const vector1 = [1, 0, 0]
const vector2 = [0, 1, 0]
// Act(执行)
const similarity = calculateCosineSimilarity(vector1, vector2)
// Assert(断言)
expect(similarity).toBe(0)
})
// ✅ 好的做法:描述性的测试名称
test('returns empty array when no markets match query', () => { })
test('throws error when OpenAI API key is missing', () => { })
test('falls back to substring search when Redis unavailable', () => { })
// ❌ 坏的做法:模糊的测试名称
test('works', () => { })
test('test search', () => { })
注意以下反模式:
// ❌ 坏的做法:函数 > 50 行
function processMarketData() {
// 100 行代码
}
// ✅ 好的做法:拆分为更小的函数
function processMarketData() {
const validated = validateData()
const transformed = transformData(validated)
return saveData(transformed)
}
// ❌ 坏的做法:5+ 层嵌套
if (user) {
if (user.isAdmin) {
if (market) {
if (market.isActive) {
if (hasPermission) {
// 做某事
}
}
}
}
}
// ✅ 好的做法:提前返回
if (!user) return
if (!user.isAdmin) return
if (!market) return
if (!market.isActive) return
if (!hasPermission) return
// 做某事
// ❌ 坏的做法:未经说明的数字
if (retryCount > 3) { }
setTimeout(callback, 500)
// ✅ 好的做法:命名常量
const MAX_RETRIES = 3
const DEBOUNCE_DELAY_MS = 500
if (retryCount > MAX_RETRIES) { }
setTimeout(callback, DEBOUNCE_DELAY_MS)
记住:代码质量不可妥协。清晰、可维护的代码能够实现快速开发和自信重构。