Instatic代码风格指南:命名规范与格式
【免费下载链接】InstaticInstatic is a modern self-hosted visual CMS - get it running in 1 minute项目地址: https://gitcode.com/GitHub_Trending/in/Instatic
Instatic是一个现代化的自托管可视化CMS系统,采用TypeScript编写并运行在Bun运行时上。本文将详细介绍Instatic项目的代码风格指南,包括命名规范、文件组织、类型安全和架构约定,帮助开发者快速掌握这个项目的编码标准。
目录
- 项目架构概览
- 命名规范
- 类型安全与TypeBox
- React组件与状态管理
- CSS与设计系统
- 数据库与迁移
- 错误处理模式
- 工具与验证
项目架构概览
Instatic采用单一代码库架构,所有功能都集成在一个Bun服务器中。前端使用React 19并启用React Compiler,后端使用Bun.serve构建的自定义路由器。项目严格遵循"验证然后信任"的原则,所有无类型边界都通过TypeBox进行验证。
命名规范
文件与目录命名
- kebab-case命名:所有文件和目录名使用短横线连接,例如:
api-client.ts、typebox-helpers.ts - 组件文件:React组件文件使用大驼峰命名,如
Button.tsx,对应的CSS模块文件为Button.module.css - 测试文件:测试文件使用
.test.ts后缀,如button-primitive-usage.test.ts - 模块组织:
src/core/- 核心引擎代码src/admin/- 管理界面React应用src/ui/- 共享UI组件src/modules/- 内置模块server/- 服务器端代码
变量与函数命名
- camelCase命名:变量和函数使用小驼峰命名法
- 布尔变量:以
is、has、can等前缀开头,如isLoading、hasPermission - TypeBox模式:模式变量以
Schema结尾,如UserSchema、PageTreeSchema - 类型推断:使用
Static<typeof Schema>获取类型,而不是单独定义接口
// ✅ 正确:模式作为唯一来源 const UserSchema = Type.Object({ id: Type.String(), email: Type.String({ format: 'email' }) }) type User = Static<typeof UserSchema> // ❌ 错误:不要定义重复的接口 interface User { id: string email: string }常量命名
- UPPER_SNAKE_CASE:配置常量、枚举值使用全大写蛇形命名
- JSON列命名:数据库中的JSON列必须以
_json结尾,如settings_json
类型安全与TypeBox
Instatic完全采用TypeBox作为类型验证的单一来源,禁止使用Zod。所有无类型边界都必须通过TypeBox模式进行验证。
边界验证模式
// HTTP请求边界 const body = parseValue(RequestBodySchema, await req.json()) // JSON解析边界 const data = safeParseJson(rawJson, DataSchema) // 软边界回退 const prefs = parseJsonWithFallback( localStorage.getItem('prefs') ?? '', PreferencesSchema, DEFAULT_PREFERENCES )HTTP客户端统一接口
所有浏览器到服务器的调用都通过apiRequest函数进行:
import { apiRequest } from '@core/http' // 标准调用方式 const result = await apiRequest('/api/users', { method: 'POST', body: { email, password }, schema: UserSchema })React组件与状态管理
组件编写规范
- 无手动记忆化:React Compiler已启用,禁止手动使用
useMemo、useCallback、memo() - 状态突变模式:使用draft-mutation风格:
set((s) => { s.x = … }) - UI组件使用:所有交互控件必须使用
src/ui/components/中的原始组件
// ✅ 正确:让编译器处理记忆化 function UserList({ users }: { users: User[] }) { return users.map(user => <UserCard key={user.id} user={user} />) } // ❌ 错误:不要手动记忆化 const memoizedUsers = useMemo(() => users.map(...), [users])三个例外情况
只有以下三种情况可以保留记忆化:
- 依赖数组中的函数:当函数被用在
useEffect依赖数组中时 - 热路径组件:在列表渲染的递归组件等性能关键路径上
- 编译器无法编译:使用
"use no memo"指令标记
CSS与设计系统
设计令牌原则
Instatic采用两层色彩模型:基础层为无色系,色彩层用于标识和状态。
- 无色基础:表面、边框、默认文本使用中性色
- 语义色彩:使用
--accent-1到--accent-10表示分类标识 - 状态色彩:使用
--editor-danger、--editor-warning等表示状态
CSS模块规则
- 仅CSS模块:禁止使用Tailwind工具类
- 无硬编码颜色:所有颜色必须来自
src/styles/globals.css中的设计令牌 - 无CSS变量回退:禁止使用
var(--name, fallback)语法 - camelCase类名:CSS模块中的类名使用小驼峰命名
/* ✅ 正确:使用设计令牌 */ .button { background-color: var(--bg-surface-2); border-radius: var(--radius); } /* ❌ 错误:硬编码颜色 */ .button { background-color: #1b1b1b; /* 禁止! */ border-radius: 6px; /* 禁止! */ }边框半径规范
--editor-radius-sm(3px):紧凑徽章--editor-radius(6px):默认编辑器控件--panel-radius(12px):浮动面板- 16px:卡片圆角
数据库与迁移
方言无关的SQL
所有数据库操作必须使用ANSI标准SQL:
// ✅ 正确:方言无关 db.query('SELECT * FROM users WHERE id = ?', [id]) // ❌ 错误:Postgres特定语法 db.query('SELECT * FROM users WHERE id = $1', [id])迁移管理
- 双向迁移:所有迁移必须在
migrations-pg.ts和migrations-sqlite.ts中都有对应版本 - 仅添加不删除:迁移必须是增量的,不能删除已有列或表
- 相同ID:两个文件中的迁移ID必须一致
错误处理模式
错误边界
所有错误处理遵循"验证然后信任"的原则:
// 硬边界:验证失败则抛出 try { const body = parseValue(RequestBodySchema, await req.json()) } catch (err) { throw new ApiError('Invalid request', 400) } // 软边界:验证失败则回退 const settings = parseJsonWithFallback( localStorage.getItem('settings'), SettingsSchema, DEFAULT_SETTINGS )用户可见错误
操作失败通过全局toast系统显示:
import { pushToast } from '@ui/components/Toast' try { await saveChanges() } catch (err) { pushToast({ kind: 'error', title: '保存失败', body: getErrorMessage(err, '未知错误') }) }工具与验证
开发工具
- Bun运行时:使用Bun而不是Node.js
- 类型检查:
bun run build运行tsc -b && vite build - 代码质量:
bun run lint执行ESLint检查 - 架构测试:
bun test运行包括架构门控测试
架构门控测试
Instatic使用架构测试确保代码质量:
css-token-policy.test.ts:禁止硬编码颜色no-tailwind-deps.test.ts:禁止Tailwind依赖db-json-column-naming.test.ts:JSON列命名规范boundary-validation.test.ts:边界验证要求
总结
Instatic的代码风格指南强调一致性、类型安全和架构清晰度。通过严格的命名规范、统一的TypeBox验证、React Compiler的自动记忆化和设计令牌系统,项目保持了高度的可维护性和可扩展性。
关键要点:
- TypeBox作为单一来源:所有类型定义都来自模式
- 无手动记忆化:信任React Compiler
- 设计令牌驱动:CSS中无硬编码值
- 方言无关的SQL:支持Postgres和SQLite
- 验证然后信任:所有边界都有类型验证
遵循这些规范将确保您的代码与Instatic的架构保持一致,并能够通过所有的门控测试。
【免费下载链接】InstaticInstatic is a modern self-hosted visual CMS - get it running in 1 minute项目地址: https://gitcode.com/GitHub_Trending/in/Instatic
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考