
agentic-awesome-skills 编码规范实战详解覆盖 TypeScript、React、Node.js 与 API 设计的通用代码质量标准【免费下载链接】agentic-awesome-skillsAAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and planning, backed by 2,600 agentic skills. Includes CLI, local MCP, catalog, plugins, and Workbench.项目地址: https://gitcode.com/GitHub_Trending/an/agentic-awesome-skills本文以 AASagentic-awesome-skills仓库中cc-skill-coding-standards技能的详细指南references/detailed-guide.md为核心骨架展开逐节完整继承其命名规范、不可变更新、错误处理、类型安全、组件结构、API 契约、文件组织、注释、性能优化、测试与坏味道检测等全部要点并结合 SKILL.md 的元信息与 skills_index.json 的索引记录加以佐证。读者读完后可以把它当作一套可直接落地的「可执行编码标准清单」在编写或评审任何 TypeScript / JavaScript / React / Node.js 项目代码时对照使用。cc-skill-coding-standards是 AAS 技能库中面向所有项目通用的编码标准类技能它不绑定某个业务模块而是定义了一套跨项目适用的「质量底线」。从仓库索引看该技能被标记为category: meta、risk: critical、source: community加入时间为2026-02-27并在 skills_index.json 中声明对 Codex 与 Claude 两类 Agent 目标均supportedplugin.targets.codex/plugin.targets.claude均为supported。技能根文件 SKILL.md 明确要求在执行本技能前必须先通读详细指南并把其中的安全前提与校验要求视为强制性约束。一、代码质量四项核心原则所有具体规范都建立在四条经典工程原则之上它们是后续每个章节的判据来源。1. Readability First可读性优先代码被阅读的次数远多于被书写的次数可读性是第一优先级变量与函数命名必须清晰让意图自明优先「自文档化代码」self-documenting code注释只补充代码无法表达的信息保持统一的格式化风格减少读者切换成本。2. KISSKeep It Simple, Stupid选择能工作的最简单方案而不是最「聪明」的方案避免过度设计over-engineering不做过早优化premature optimization「易于理解」永远优于「炫技代码」。3. DRYDont Repeat Yourself把公共逻辑抽取为函数创建可复用的组件与工具模块跨模块共享工具函数杜绝复制粘贴式编程——每处重复都是未来 bug 的潜在来源。4. YAGNIYou Arent Gonna Need It不在需求到来之前预构功能避免投机性泛化speculative generality只在确实需要时增加复杂度先简单起步需要时再重构演进。这四条原则在 AAS 技能库中被定位为risk: critical意味着在代码生成、代码评审类工作流中它们属于「违反即扣分」的硬性约束而非可选项。二、TypeScript / JavaScript 编码标准1. 变量命名描述性优于缩写使用能表达语义的完整名称杜绝无意义的单字母或模糊布尔量// ✅ GOOD: Descriptive names const marketSearchQuery election const isUserAuthenticated true const totalRevenue 1000 // ❌ BAD: Unclear names const q election const flag true const x 1000布尔值建议采用is/has/can等前缀如isUserAuthenticated数量型变量采用total/count等前缀如totalRevenue搜索查询等上下文型变量带上领域词如marketSearchQuery。2. 函数命名动词 名词 模式函数名应描述「动作 对象」让调用点读起来像一句自然语言// ✅ GOOD: Verb-noun pattern async function fetchMarketData(marketId: string) { } function calculateSimilarity(a: number[], b: number[]) { } function isValidEmail(email: string): boolean { } // ❌ BAD: Unclear or noun-only async function market(id: string) { } function similarity(a, b) { } function email(e) { }同时为函数标注完整的参数类型与返回值类型如a: number[]、: boolean让类型成为签名的一部分。3. 不可变更新模式CRITICAL强制React / Node.js 项目中对象与数组的更新必须使用展开运算符spread创建新引用严禁直接修改原对象或原数组——这是避免 React 渲染失效、并发状态错乱的最关键约定// ✅ ALWAYS use spread operator const updatedUser { ...user, name: New Name } const updatedArray [...items, newItem] // ❌ NEVER mutate directly user.name New Name // BAD items.push(newItem) // BAD注意新增数组元素使用[...items, newItem]生成新数组而不是items.push(...)更新对象属性使用{ ...user, name: New Name }而不是直接赋值user.name ...。该节在原文档中被显式标注为 CRITICAL 级别属于必须无条件遵守的硬性规则。4. 错误处理全面捕获绝不静默失败异步函数必须捕获网络 / 状态类错误检查 HTTP 状态码并向上层抛出带上下文的新错误// ✅ GOOD: Comprehensive error handling 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) } } // ❌ BAD: No error handling async function fetchData(url) { const response await fetch(url) return response.json() }要点response.ok false时显式抛错并携带status/statusTextcatch 块中先记录原始错误console.error再抛出对调用方有意义的封装错误避免吞掉异常或丢失根因。5. Async / Await能并行就不要串行互不依赖的异步任务用Promise.all并行执行减少总等待时间// ✅ GOOD: Parallel execution when possible const [users, markets, stats] await Promise.all([ fetchUsers(), fetchMarkets(), fetchStats() ]) // ❌ BAD: Sequential when unnecessary const users await fetchUsers() const markets await fetchMarkets() const stats await fetchStats()6. 类型安全消灭any用接口interface与联合类型union type描述数据形状函数签名返回强类型 Promise// ✅ GOOD: Proper types interface Market { id: string name: string status: active | resolved | closed created_at: Date } function getMarket(id: string): PromiseMarket { // Implementation } // ❌ BAD: Using any function getMarket(id: any): Promiseany { // Implementation }status使用字面量联合类型active | resolved | closed而非string让非法状态在编译期即被拦截任何any的出现都应视为技术债。三、React 最佳实践1. 组件结构函数组件 完整 Props 类型组件必须使用带类型的函数组件通过interface显式声明 Props并给出默认值// ✅ GOOD: Functional component with types 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 ) } // ❌ BAD: No types, unclear structure export function Button(props) { return button onClick{props.onClick}{props.children}/button }variant同样采用联合类型限定取值范围可选 Propsdisabled、variant在解构时赋予默认值保证组件行为可预测。2. 自定义 Hooks封装可复用逻辑把可复用的副作用逻辑封装为use前缀的自定义 Hook并保持泛型通用// ✅ GOOD: Reusable custom hook export function useDebounceT(value: T, delay: number): T { const [debouncedValue, setDebouncedValue] useStateT(value) useEffect(() { const handler setTimeout(() { setDebouncedValue(value) }, delay) return () clearTimeout(handler) }, [value, delay]) return debouncedValue } // Usage const debouncedQuery useDebounce(searchQuery, 500)要点useEffect的 cleanup 中调用clearTimeout防止内存泄漏依赖数组[value, delay]保证 timer 在输入变化时重置返回去抖后的值供组件直接消费。3. 状态管理优先函数式更新基于前一个状态计算新状态时使用函数式更新setCount(prev prev 1)避免异步场景中的过期闭包stale closure// ✅ GOOD: Proper state updates const [count, setCount] useState(0) // Functional update for state based on previous state setCount(prev prev 1) // ❌ BAD: Direct state reference setCount(count 1) // Can be stale in async scenarios4. 条件渲染短路表达式拒绝三元地狱加载、错误、数据三种状态分别用短路渲染保持 JSX 平铺可读// ✅ GOOD: Clear conditional rendering {isLoading Spinner /} {error ErrorMessage error{error} /} {data DataDisplay data{data} /} // ❌ BAD: Ternary hell {isLoading ? Spinner / : error ? ErrorMessage error{error} / : data ? DataDisplay data{data} / : null}四、API 设计标准1. REST 路由约定资源名使用复数名词方法语义与 HTTP 动词一一对应GET /api/markets # List all markets GET /api/markets/:id # Get specific market POST /api/markets # Create new market PUT /api/markets/:id # Update market (full) PATCH /api/markets/:id # Update market (partial) DELETE /api/markets/:id # Delete market # Query parameters for filtering GET /api/markets?statusactivelimit10offset0约定要点PUT表示全量替换PATCH表示局部更新列表接口统一通过 query string 提供过滤status与分页limit/offset。2. 统一响应格式所有接口返回一致的响应信封envelope成功与失败路径结构对称// ✅ GOOD: Consistent response structure interface ApiResponseT { success: boolean data?: T error?: string meta?: { total: number page: number limit: number } } // Success response return NextResponse.json({ success: true, data: markets, meta: { total: 100, page: 1, limit: 10 } }) // Error response return NextResponse.json({ success: false, error: Invalid request }, { status: 400 })meta中携带分页元数据total/page/limit前端可直接渲染分页器错误响应同时配合 HTTP 状态码如 400。3. 输入校验Schema 优先使用 zod 在进入业务逻辑前完成请求体校验失败时返回结构化错误明细import { z } from zod // ✅ GOOD: Schema validation 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) // Proceed with validated data } catch (error) { if (error instanceof z.ZodError) { return NextResponse.json({ success: false, error: Validation failed, details: error.errors }, { status: 400 }) } } }字段约束示例展示了常用的长度边界min(1).max(200)、日期格式.datetime()与非空数组array(...).min(1)校验错误对象error.errors直接返回给客户端便于定位具体字段。五、文件组织1. 项目目录结构Next.js App Router 示例按职责分层组织源码路由、组件、Hook、工具、类型、样式各归其位src/ ├── app/ # Next.js App Router │ ├── api/ # API routes │ ├── markets/ # Market pages │ └── (auth)/ # Auth pages (route groups) ├── components/ # React components │ ├── ui/ # Generic UI components │ ├── forms/ # Form components │ └── layouts/ # Layout components ├── hooks/ # Custom React hooks ├── lib/ # Utilities and configs │ ├── api/ # API clients │ ├── utils/ # Helper functions │ └── constants/ # Constants ├── types/ # TypeScript types └── styles/ # Global styles路由组(auth)用于组织页面而不污染 URL 路径components/ui存放通用 UI 原子组件components/forms、components/layouts分别存放表单与布局类组件。2. 文件命名约定不同类型的文件采用不同的大小写风格形成一眼可辨的命名规律components/Button.tsx # PascalCase for components hooks/useAuth.ts # camelCase with use prefix lib/formatDate.ts # camelCase for utilities types/market.types.ts # camelCase with .types suffix组件文件PascalCaseButton.tsxHook 文件camelCase 且带use前缀useAuth.ts工具函数camelCaseformatDate.ts类型文件camelCase 加.types后缀market.types.ts。六、注释与文档规范1. 注释时机解释 WHY不解释 WHAT注释只用于代码无法自明的内容——原因、权衡、性能取舍// ✅ GOOD: Explain WHY, not WHAT // Use exponential backoff to avoid overwhelming the API during outages const delay Math.min(1000 * Math.pow(2, retryCount), 30000) // Deliberately using mutation here for performance with large arrays items.push(newItem) // ❌ BAD: Stating the obvious // Increment counter by 1 count // Set name to users name name user.name示例中的两处「好注释」都记录了代码背后的决策理由退避策略、刻意使用可变操作而「坏注释」只是把代码复述了一遍属于噪音。2. 公开 API 的 JSDoc对外暴露的函数必须使用 JSDoc 三件套param说明参数与默认值、returns说明返回值、throws说明异常场景并附带example可运行示例/** * Searches markets using semantic similarity. * * param query - Natural language search query * param limit - Maximum number of results (default: 10) * returns Array of markets sorted by similarity score * throws {Error} If OpenAI API fails or Redis unavailable * * 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 ): PromiseMarket[] { // Implementation }example中的注释式输出// Trump vs Biden让调用者在 IDE 中即可预览预期行为无需跳转实现。七、性能最佳实践1. 记忆化useMemo / useCallback昂贵计算用useMemo缓存回调函数用useCallback稳定引用避免子组件无谓重渲染import { useMemo, useCallback } from react // ✅ GOOD: Memoize expensive computations const sortedMarkets useMemo(() { return markets.sort((a, b) b.volume - a.volume) }, [markets]) // ✅ GOOD: Memoize callbacks const handleSearch useCallback((query: string) { setSearchQuery(query) }, [])依赖数组必须写全[markets]/[]否则记忆化结果会失效或使用过期数据。2. 懒加载lazy Suspense体积大、首屏不需要的重组件用React.lazy按需加载配合Suspense提供加载占位import { lazy, Suspense } from react // ✅ GOOD: Lazy load heavy components const HeavyChart lazy(() import(./HeavyChart)) export function Dashboard() { return ( Suspense fallback{Spinner /} HeavyChart / /Suspense ) }3. 数据库查询只取需要的列查询时显式列出需要的字段禁止无脑select(*)// ✅ GOOD: Select only needed columns const { data } await supabase .from(markets) .select(id, name, status) .limit(10) // ❌ BAD: Select everything const { data } await supabase .from(markets) .select(*)八、测试标准1. AAA 结构Arrange – Act – Assert每个测试用例严格按「准备 → 执行 → 断言」三阶段组织可读性即断言的可信度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) })2. 测试命名描述行为而非过程测试名应以「在什么条件下、发生什么结果」的句子形态书写拒绝works这类空泛命名// ✅ GOOD: Descriptive test names 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, () { }) // ❌ BAD: Vague test names test(works, () { }) test(test search, () { })好的测试名同时起到了「行为文档」的作用throws error when OpenAI API key is missing直接描述了依赖缺失时的契约行为falls back to substring search when Redis unavailable则记录了降级策略。九、代码坏味道检测清单评审代码时逐项排查以下三类高频反模式1. 长函数超过 50 行超长函数应被拆分为多个职责单一的小函数通过清晰的调用链表达流程// ❌ BAD: Function 50 lines function processMarketData() { // 100 lines of code } // ✅ GOOD: Split into smaller functions function processMarketData() { const validated validateData() const transformed transformData(validated) return saveData(transformed) }2. 深层嵌套5 层以上用「提前返回early return」拍平嵌套把守卫条件逐个前置// ❌ BAD: 5 levels of nesting if (user) { if (user.isAdmin) { if (market) { if (market.isActive) { if (hasPermission) { // Do something } } } } } // ✅ GOOD: Early returns if (!user) return if (!user.isAdmin) return if (!market) return if (!market.isActive) return if (!hasPermission) return // Do something3. 魔法数字Magic Numbers裸数字无法表达意图必须提取为命名常量// ❌ BAD: Unexplained numbers if (retryCount 3) { } setTimeout(callback, 500) // ✅ GOOD: Named constants const MAX_RETRIES 3 const DEBOUNCE_DELAY_MS 500 if (retryCount MAX_RETRIES) { } setTimeout(callback, DEBOUNCE_DELAY_MS)命名常量采用UPPER_SNAKE_CASE并在名称中带上单位_MS让数值语义一目了然。十、在 Agent 工作流中使用本规范cc-skill-coding-standards在 AAS 技能库中的定位是通用元技能category: meta意味着它可叠加到任何代码生成、重构、评审任务上作为质量标准层。结合 SKILL.md 的约束使用时请注意触发条件仅当任务与上述范围TypeScript / JavaScript / React / Node.js 开发、API 设计、代码评审明确匹配时才启用本技能不适用于无关场景验证前提本规范的输出不能替代环境相关的专项验证、测试或专家评审——代码通过本清单检查后仍需运行真实测试与构建澄清机制当所需的输入、权限、安全边界或成功标准缺失时应停下并向用户澄清而不是强行执行加载策略聚焦单一任务时按需加载对应章节如只写 React 组件就加载第三节端到端完整执行时应通读全文。仓库中同一技能同时存在于 skills/cc-skill-coding-standards 目录技能源目录与 plugins/agentic-awesome-skills-claude/skills/cc-skill-coding-standardsClaude 插件打包目录两个副本的SKILL.md均指向references/detailed-guide.md作为完整规程与参考材料根技能文件只保留激活条件、使用示例、安全约束与局限说明——这种「根文件精简 详细指南分卷」的结构正是为了让 Agent 在上下文有限时也能按需加载是阅读本仓库其他技能时值得借鉴的组织模式。小结代码质量不是可协商项。清晰、可维护的代码是快速迭代与自信重构的前提——这正是cc-skill-coding-standards作为risk: critical技能存在的意义它不是一份供人欣赏的文档而是一套可以在每次提交前、每次评审中逐条对照执行的硬性检查清单。【免费下载链接】agentic-awesome-skillsAAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and planning, backed by 2,600 agentic skills. Includes CLI, local MCP, catalog, plugins, and Workbench.项目地址: https://gitcode.com/GitHub_Trending/an/agentic-awesome-skills创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考