# 代码风格指南
**🌍 Language / 语言** [🇺🇸 English](./Code-Style.en.md) | [🇨🇳 中文](./Code-Style.md)
本指南概述了 AI Proxy Worker 项目的编码标准和最佳实践。遵循这些准则确保整个项目的代码一致性、可维护性和可读性。 ## 📋 通用原则 ### 代码质量标准 - **可读性优先**:编写能讲述故事的代码 - **一致性**:在整个代码库中遵循既定模式 - **简洁性**:优先选择简单的解决方案而非复杂的 - **模块化设计**:拆分复杂函数为单一职责的小函数 - **低认知复杂度**:保持函数的认知复杂度在15以下 - **性能**:考虑代码的性能影响 - **安全性**:在实现中始终优先考虑安全性 ### 文件组织 ``` ai-proxy-worker/ ├── worker.js # 主要 worker 脚本 ├── wrangler.toml # 配置文件 ├── docs/ # 文档 ├── examples/ # 使用示例 └── tests/ # 测试文件(未来) ``` ## 🔧 JavaScript/TypeScript 标准 ### 代码格式化 - **缩进**:使用 2 个空格(不使用制表符) - **行长度**:每行最多 100 个字符 - **分号**:可选,但要保持一致 - **引号**:字符串使用单引号 - **尾随逗号**:在多行对象/数组中使用尾随逗号 ```javascript // ✅ 好的示例 const config = { apiUrl: 'https://api.deepseek.com', timeout: 30000, retries: 3, } const models = [ 'deepseek-chat', 'deepseek-reasoner', ] // ❌ 避免这样写 const config = { "apiUrl": "https://api.deepseek.com", "timeout": 30000, "retries": 3 }; ``` ### 命名约定 #### 变量和函数 变量和函数使用 camelCase: ```javascript // ✅ 好的示例 const apiResponse = await fetchData() const userMessage = request.body.message const isValidRequest = validateInput(data) function processUserRequest(request) { // 实现 } async function sendUpstreamRequest(payload) { // 实现 } // ❌ 避免这样写 const api_response = await fetchData() const user_message = request.body.message const IsValidRequest = validateInput(data) function ProcessUserRequest(request) { // 实现 } ``` #### 常量 常量使用 UPPER_SNAKE_CASE: ```javascript // ✅ 好的示例 const API_BASE_URL = 'https://api.deepseek.com' const DEFAULT_TIMEOUT = 30000 const MAX_RETRIES = 3 const SUPPORTED_MODELS = ['deepseek-chat', 'deepseek-reasoner'] // ❌ 避免这样写 const apiBaseUrl = 'https://api.deepseek.com' const defaultTimeout = 30000 ``` #### 类和对象 类和构造函数使用 PascalCase: ```javascript // ✅ 好的示例 class RequestHandler { constructor(config) { this.config = config } } class ApiError extends Error { constructor(message, statusCode) { super(message) this.statusCode = statusCode } } // ❌ 避免这样写 class requestHandler { // 实现 } ``` ### 函数结构 #### 函数声明 短函数优先使用箭头函数,复杂逻辑使用常规函数: ```javascript // ✅ 好的示例 - 短工具函数 const isValidModel = (model) => SUPPORTED_MODELS.includes(model) const createErrorResponse = (message, status = 400) => new Response(JSON.stringify({ error: message }), { status }) // ✅ 好的示例 - 复杂函数 async function handleChatRequest(request, env) { try { // 验证请求 const validation = await validateRequest(request) if (!validation.valid) { return createErrorResponse(validation.error, 400) } // 处理请求 const response = await processChat(request, env) return response } catch (error) { console.error('聊天请求失败:', error) return createErrorResponse('内部服务器错误', 500) } } ``` #### 参数处理 对象参数使用解构: ```javascript // ✅ 好的示例 async function processChat({ messages, model, temperature }, env) { // 实现 } // 带验证的替代方案 async function processChat(params, env) { const { messages, model, temperature = 0.7 } = params // 验证必需参数 if (!messages || !model) { throw new Error('缺少必需参数') } // 实现 } // ❌ 避免这样写 async function processChat(params, env) { const messages = params.messages const model = params.model const temperature = params.temperature // 实现 } ``` ## 📝 文档标准 ### JSDoc 注释 函数文档使用 JSDoc: ```javascript /** * 向上游 API 发送聊天请求 * @param {Object} request - 聊天请求对象 * @param {Array} request.messages - 聊天消息数组 * @param {string} request.model - 要使用的模型 * @param {number} [request.temperature=0.7] - 采样温度 * @param {Object} env - 环境变量 * @param {string} env.DEEPSEEK_API_KEY - DeepSeek API 密钥 * @returns {Promise} API 响应 * @throws {Error} 当 API 密钥缺失或请求失败时 */ async function sendChatRequest(request, env) { // 实现 } ``` ### 行内注释 使用注释解释复杂逻辑: ```javascript // ✅ 好的示例 - 解释"为什么" async function handleRequest(request, env) { // 提取客户端 IP 用于速率限制 const clientIP = request.headers.get('CF-Connecting-IP') || request.headers.get('X-Forwarded-For') || 'unknown' // 在处理昂贵操作之前检查速率限制 if (!await checkRateLimit(clientIP)) { return new Response('超出速率限制', { status: 429 }) } // 处理实际请求 return await processRequest(request, env) } // ❌ 避免这样写 - 陈述显而易见的事实 async function handleRequest(request, env) { // 获取客户端 IP const clientIP = request.headers.get('CF-Connecting-IP') // 返回速率限制响应 if (!await checkRateLimit(clientIP)) { return new Response('超出速率限制', { status: 429 }) } } ``` ## 🔧 模块化验证架构 ### 验证函数设计原则 本项目采用模块化验证架构,将复杂的验证逻辑拆分为多个单一职责的函数: ```javascript // ✅ 好的示例 - 模块化验证 async function validateRequest(request) { validateContentType(request); // 验证Content-Type validateContentLength(request); // 验证请求大小 if (CONFIG.VALIDATE_REQUEST_BODY) { await validateRequestBody(request); // 验证请求体 } } function validateContentType(request) { const contentType = request.headers.get('content-type') || ''; if (!contentType.includes('application/json')) { throw new Error('Invalid content type. Expected application/json'); } } async function validateRequestBody(request) { try { const body = await request.clone().json(); validateMessages(body.messages); // 验证消息数组 validateModel(body.model); // 验证模型 } catch (e) { // 错误处理逻辑 } } ``` ### 函数复杂度控制 - **认知复杂度限制**: 每个函数保持认知复杂度 ≤ 15 - **单一职责原则**: 每个验证函数只负责一种验证 - **可组合性**: 验证函数可以独立测试和复用 ```javascript // ✅ 好的示例 - 单一职责 function validateSingleMessage(message) { if (!message.role || !message.content) { throw new Error('Invalid request format. Each message must have role and content'); } if (!['system', 'user', 'assistant', 'tool'].includes(message.role)) { throw new Error('Invalid request format. Invalid message role'); } } // ❌ 避免这样写 - 复杂的巨大函数 function validateEverything(request) { // 100+ 行验证代码,认知复杂度 > 20 } ``` ## 🛡️ 错误处理 ### 错误响应格式 使用一致的错误响应格式: ```javascript // ✅ 好的示例 - 一致的错误格式 function createErrorResponse(error, statusCode = 500, details = null) { const errorResponse = { error: error.code || 'unknown_error', message: error.message || '发生意外错误', timestamp: new Date().toISOString(), } // 在开发/调试模式下添加详细信息 if (details && env.DEBUG_MODE === 'true') { errorResponse.details = details } return new Response(JSON.stringify(errorResponse), { status: statusCode, headers: { 'Content-Type': 'application/json' } }) } // 使用方法 try { const result = await riskyOperation() return new Response(JSON.stringify(result)) } catch (error) { console.error('操作失败:', error) return createErrorResponse(error, 500, { operation: 'riskyOperation' }) } ``` ### 错误类型 为不同场景定义自定义错误类型: ```javascript // ✅ 好的示例 - 自定义错误类 class ValidationError extends Error { constructor(message, field = null) { super(message) this.name = 'ValidationError' this.code = 'validation_error' this.field = field } } class ApiError extends Error { constructor(message, statusCode = 500, originalError = null) { super(message) this.name = 'ApiError' this.code = 'api_error' this.statusCode = statusCode this.originalError = originalError } } // 使用方法 function validateChatRequest(data) { if (!data.messages || !Array.isArray(data.messages)) { throw new ValidationError('消息必须是数组', 'messages') } if (!data.model || typeof data.model !== 'string') { throw new ValidationError('模型必须是字符串', 'model') } } ``` ## 🔒 安全最佳实践 ### 输入验证 始终验证和清理输入: ```javascript // ✅ 好的示例 - 全面验证 function validateChatRequest(data) { const errors = [] // 必需字段 if (!data.messages || !Array.isArray(data.messages)) { errors.push('messages 必须是数组') } if (!data.model || typeof data.model !== 'string') { errors.push('model 必须是字符串') } // 验证消息数组 if (data.messages) { data.messages.forEach((msg, index) => { if (!msg.role || !['user', 'assistant', 'system'].includes(msg.role)) { errors.push(`messages[${index}].role 必须是 user、assistant 或 system`) } if (!msg.content || typeof msg.content !== 'string') { errors.push(`messages[${index}].content 必须是非空字符串`) } // 内容长度限制 if (msg.content && msg.content.length > 100000) { errors.push(`messages[${index}].content 超过最大长度`) } }) } // 可选参数验证 if (data.temperature !== undefined) { if (typeof data.temperature !== 'number' || data.temperature < 0 || data.temperature > 2) { errors.push('temperature 必须是 0 到 2 之间的数字') } } return { valid: errors.length === 0, errors } } ``` ### 敏感数据处理 永远不要记录敏感信息: ```javascript // ✅ 好的示例 - 清理后的日志 function logRequest(request, response) { const logData = { method: request.method, url: new URL(request.url).pathname, // 不记录查询参数 status: response.status, timestamp: new Date().toISOString(), // 不记录授权头或正文内容 } console.log('请求已处理:', logData) } // ❌ 避免这样写 - 记录敏感数据 function logRequest(request, response) { console.log('请求:', { headers: Object.fromEntries(request.headers), // 包含 API 密钥! body: request.body, // 包含用户数据! url: request.url // 可能包含敏感查询参数! }) } ``` ## ⚡ 性能指南 ### Async/Await 最佳实践 正确使用 async/await: ```javascript // ✅ 好的示例 - 尽可能并行执行 async function processMultipleRequests(requests, env) { // 并行执行请求 const promises = requests.map(request => processRequest(request, env)) const results = await Promise.allSettled(promises) return results.map(result => result.status === 'fulfilled' ? result.value : null ).filter(Boolean) } // ✅ 好的示例 - 需要时顺序执行 async function processWithDependencies(request, env) { const validation = await validateRequest(request) if (!validation.valid) { throw new ValidationError(validation.errors.join(', ')) } const processed = await processRequest(request, env) const logged = await logRequest(processed) return processed } // ❌ 避免这样写 - 不必要的顺序执行 async function processMultipleRequests(requests, env) { const results = [] for (const request of requests) { const result = await processRequest(request, env) // 阻塞! results.push(result) } return results } ``` ### 内存管理 注意内存使用: ```javascript // ✅ 好的示例 - 清理资源 async function processLargeRequest(request, env) { let reader = null try { reader = request.body.getReader() const chunks = [] while (true) { const { done, value } = await reader.read() if (done) break chunks.push(value) } return await processChunks(chunks) } finally { // 清理资源 if (reader) { reader.releaseLock() } } } ``` ## 🧪 测试指南 ### 测试结构 编写测试时(未来实现): ```javascript // ✅ 好的示例 - 清晰的测试结构 describe('聊天请求处理器', () => { describe('validateChatRequest', () => { it('应该接受有效的聊天请求', () => { const validRequest = { messages: [{ role: 'user', content: '你好' }], model: 'deepseek-chat' } const result = validateChatRequest(validRequest) expect(result.valid).toBe(true) }) it('应该拒绝没有消息的请求', () => { const invalidRequest = { model: 'deepseek-chat' } const result = validateChatRequest(invalidRequest) expect(result.valid).toBe(false) expect(result.errors).toContain('messages 必须是数组') }) }) }) ``` ## 📋 代码审查清单 提交代码前,确保: ### 功能性 - [ ] 代码按预期工作 - [ ] 处理边界情况 - [ ] 正确管理错误条件 - [ ] 考虑性能影响 ### 代码质量 - [ ] 遵循项目命名约定 - [ ] 函数大小合理(< 50 行) - [ ] 代码自文档化 - [ ] 复杂逻辑有注释 - [ ] 没有遗留调试代码 ### 安全性 - [ ] 实现输入验证 - [ ] 日志中无敏感数据 - [ ] 适当的错误处理不泄露信息 - [ ] 适当设置安全头 ### 文档 - [ ] 公共函数有 JSDoc 注释 - [ ] 需要时更新 README - [ ] 为新功能提供示例 - [ ] 记录重大变更 --- **一致的代码风格让协作更容易** ✨ 遵循这些指南有助于维护高质量、可维护的代码库,让所有贡献者都能轻松使用。