mit einem Klick
coding-standards
Universal coding standards, best practices, and patterns for TypeScript, JavaScript, React, and Node.js development.
Universal coding standards, best practices, and patterns for TypeScript, JavaScript, React, and Node.js development.
React 18/19 patterns including hooks discipline, server/client component boundaries, Suspense + error boundaries, form actions, data fetching, state management decision trees, and accessibility-first composition. Use when writing or reviewing React components.
React and Next.js performance optimization patterns adapted from Vercel Engineering's React Best Practices (https://github.com/vercel-labs/agent-skills). Organizes 70+ rules across 8 priority categories — waterfalls, bundle size, server-side, client fetching, re-render, rendering, JS micro-perf, advanced. Use when writing, reviewing, or refactoring React/Next.js code for performance.
React component testing with React Testing Library, Vitest/Jest, MSW for network mocking, accessibility assertions with axe, and the decision boundary between component tests and Playwright/Cypress end-to-end runs. Use when writing or fixing tests for React components, hooks, or pages.
Agent-driven scheduling and publishing of social media posts across 13 platforms via SocialClaw. Use when the user wants to publish to X, LinkedIn, Instagram, Facebook Pages, TikTok, Discord, Telegram, YouTube, Reddit, WordPress, or Pinterest — or when managing campaigns, uploading media, or monitoring post delivery status.
End-to-end marketing campaign planning and execution. Covers audience research, positioning, campaign angle definition, landing page copy, email sequences, social posts, ad copy, short-form video scripts, and content calendars. Use as the orchestration layer for multi-channel product launches.
Accessibility patterns for React and Next.js — semantic HTML, ARIA attributes, form labeling, keyboard navigation, focus management, and screen reader support. Use when building any interactive UI component or form.
| name | coding-standards |
| description | Universal coding standards, best practices, and patterns for TypeScript, JavaScript, React, and Node.js development. |
適用於所有專案的通用程式碼標準。
// PASS: 良好:描述性名稱
const marketSearchQuery = 'election'
const isUserAuthenticated = true
const totalRevenue = 1000
// FAIL: 不良:不清楚的名稱
const q = 'election'
const flag = true
const x = 1000
// PASS: 良好:動詞-名詞模式
async function fetchMarketData(marketId: string) { }
function calculateSimilarity(a: number[], b: number[]) { }
function isValidEmail(email: string): boolean { }
// FAIL: 不良:不清楚或只有名詞
async function market(id: string) { }
function similarity(a, b) { }
function email(e) { }
// PASS: 總是使用展開運算符
const updatedUser = {
...user,
name: 'New Name'
}
const updatedArray = [...items, newItem]
// FAIL: 永遠不要直接修改
user.name = 'New Name' // 不良
items.push(newItem) // 不良
// PASS: 良好:完整的錯誤處理
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')
}
}
// FAIL: 不良:無錯誤處理
async function fetchData(url) {
const response = await fetch(url)
return response.json()
}
// PASS: 良好:可能時並行執行
const [users, markets, stats] = await Promise.all([
fetchUsers(),
fetchMarkets(),
fetchStats()
])
// FAIL: 不良:不必要的順序執行
const users = await fetchUsers()
const markets = await fetchMarkets()
const stats = await fetchStats()
// PASS: 良好:正確的型別
interface Market {
id: string
name: string
status: 'active' | 'resolved' | 'closed'
created_at: Date
}
function getMarket(id: string): Promise<Market> {
// 實作
}
// FAIL: 不良:使用 'any'
function getMarket(id: any): Promise<any> {
// 實作
}
// PASS: 良好:具有型別的函式元件
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>
)
}
// FAIL: 不良:無型別、結構不清楚
export function Button(props) {
return <button onClick={props.onClick}>{props.children}</button>
}
// PASS: 良好:可重用的自訂 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)
// PASS: 良好:正確的狀態更新
const [count, setCount] = useState(0)
// 基於先前狀態的函式更新
setCount(prev => prev + 1)
// FAIL: 不良:直接引用狀態
setCount(count + 1) // 在非同步情境中可能過時
// PASS: 良好:清晰的條件渲染
{isLoading && <Spinner />}
{error && <ErrorMessage error={error} />}
{data && <DataDisplay data={data} />}
// FAIL: 不良:三元地獄
{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
// PASS: 良好:一致的回應結構
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'
// PASS: 良好:Schema 驗證
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 後綴
// PASS: 良好:解釋「為什麼」而非「什麼」
// 使用指數退避以避免在服務中斷時壓垮 API
const delay = Math.min(1000 * Math.pow(2, retryCount), 30000)
// 為了處理大陣列的效能,此處刻意使用突變
items.push(newItem)
// FAIL: 不良:陳述顯而易見的事實
// 將計數器加 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'
// PASS: 良好:記憶化昂貴的計算
const sortedMarkets = useMemo(() => {
return markets.sort((a, b) => b.volume - a.volume)
}, [markets])
// PASS: 良好:記憶化回呼函式
const handleSearch = useCallback((query: string) => {
setSearchQuery(query)
}, [])
import { lazy, Suspense } from 'react'
// PASS: 良好:延遲載入重型元件
const HeavyChart = lazy(() => import('./HeavyChart'))
export function Dashboard() {
return (
<Suspense fallback={<Spinner />}>
<HeavyChart />
</Suspense>
)
}
// PASS: 良好:只選擇需要的欄位
const { data } = await supabase
.from('markets')
.select('id, name, status')
.limit(10)
// FAIL: 不良:選擇所有欄位
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)
})
// PASS: 良好:描述性測試名稱
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', () => { })
// FAIL: 不良:模糊的測試名稱
test('works', () => { })
test('test search', () => { })
注意這些反模式:
// FAIL: 不良:函式超過 50 行
function processMarketData() {
// 100 行程式碼
}
// PASS: 良好:拆分為較小的函式
function processMarketData() {
const validated = validateData()
const transformed = transformData(validated)
return saveData(transformed)
}
// FAIL: 不良:5 層以上巢狀
if (user) {
if (user.isAdmin) {
if (market) {
if (market.isActive) {
if (hasPermission) {
// 做某事
}
}
}
}
}
// PASS: 良好:提前返回
if (!user) return
if (!user.isAdmin) return
if (!market) return
if (!market.isActive) return
if (!hasPermission) return
// 做某事
// FAIL: 不良:無解釋的數字
if (retryCount > 3) { }
setTimeout(callback, 500)
// PASS: 良好:命名常數
const MAX_RETRIES = 3
const DEBOUNCE_DELAY_MS = 500
if (retryCount > MAX_RETRIES) { }
setTimeout(callback, DEBOUNCE_DELAY_MS)
記住:程式碼品質是不可協商的。清晰、可維護的程式碼能實現快速開發和自信的重構。