# Opentu 项目宪章 ## 核心原则 ### I. 插件优先架构 每个功能都应该实现为遵循 `withXxx` 模式的可组合插件。插件必须满足: - **自包含**: 每个插件都有清晰的边界和职责 - **可独立测试**: 可以独立进行测试 - **可组合**: 可以与其他插件组合而不产生冲突 - **框架无关**: 核心逻辑应该能在不同的UI框架中工作(React、Angular等) **示例**: `withFreehand`、`withMind`、`withDraw`、`withHotkey` - 每个都在不耦合的情况下扩展编辑器能力 ### II. 文件大小约束(不可协商) **单个文件不得超过 500 行**(包括空行和注释) 这是一个硬性约束,以确保: - 代码可读性和可维护性 - 合理的关注点分离 - 易于代码审查和理解 - 防止出现单体组件 **执行规则**: - PR 审查必须拒绝超过 500 行的文件 - 例外情况需要架构审查和文档化的理由 - 重构为多个文件或抽象为可重用模块 ### III. 类型安全优先 TypeScript 严格模式是强制性的。所有代码必须: - 使用 `interface` 定义对象类型,`type` 定义联合类型/交叉类型 - 为所有组件 Props 定义显式类型 - 避免使用 `any` - 使用具体类型或泛型 - 提交前通过严格的 TypeScript 检查 **示例**: ```typescript // ✅ 好的做法 interface UserProfileProps { userId: string; onUpdate: (user: User) => void; } // ❌ 不好的做法 const UserProfile = (props: any) => {} ``` ### IV. 设计系统一致性 所有 UI 组件必须使用 **TDesign React** 并采用 light 主题。一致性规则: - 所有 UI 元素使用 TDesign 组件 - 遵循品牌色彩系统(橙金色、蓝紫色、创作强调色) - 使用设计系统的 CSS 变量 - Tooltip 主题必须使用 'light' - 自定义样式遵循 BEM 命名约定 ### V. 性能与优化 为用户体验进行优化: - 对昂贵的组件使用 `React.memo` - 对传递给子组件的事件处理器使用 `useCallback` - 对昂贵的计算使用 `useMemo` - 对大型组件使用 `React.lazy` 实现代码分割 - 图片懒加载并实现预加载策略 - 对长列表考虑使用虚拟化 ### VI. 安全与验证 安全性是不可协商的: - 验证和清理所有用户输入 - 永远不要硬编码敏感信息(API 密钥、密码) - API 调用使用安全的错误处理 - 从日志中过滤敏感数据 - 验证文件上传(类型、大小、内容) ### VII. Monorepo 结构 在 Nx monorepo 中保持清晰的分离: - `apps/web/` - 主 Web 应用程序 - `packages/drawnix/` - 核心白板库 - `packages/react-board/` - Plait 的 React 包装器 - `packages/react-text/` - 文本渲染组件 每个包应该有清晰的依赖关系和最小的耦合。 ## 开发标准 ### 命名约定 **文件命名**(严格执行): - 组件文件:`PascalCase.tsx`(例如 `ImageCropPopup.tsx`) - Hook 文件:`camelCase.ts`(例如 `useImageCrop.ts`) - 工具文件:`kebab-case.ts`(例如 `image-utils.ts`) - 类型文件:`kebab-case.types.ts`(例如 `image-crop.types.ts`) - 常量文件:`UPPER_SNAKE_CASE.ts`(例如 `STORAGE_KEYS.ts`) **代码命名**: - 变量:camelCase - 常量:UPPER_SNAKE_CASE - 组件:PascalCase - 接口/类型:PascalCase ### 组件结构 所有 React 组件必须遵循以下顺序: 1. 导入(第三方 → 本地) 2. 类型定义 3. 常量 4. 主组件函数 5. Hooks(useState、useEffect、自定义 hooks) 6. 事件处理器(使用 useCallback 包装) 7. 渲染逻辑 **示例**: ```typescript import React, { useState, useCallback } from 'react'; import { Button } from 'tdesign-react'; import './Component.scss'; interface ComponentProps { title: string; onAction: (data: string) => void; } const DEFAULT_CONFIG = { timeout: 5000 }; export const Component: React.FC = ({ title, onAction }) => { const [loading, setLoading] = useState(false); const handleClick = useCallback(() => { onAction(title); }, [title, onAction]); return ; }; ``` ### 测试要求 每个功能必须包括: - **单元测试** - 用于逻辑和工具函数 - **组件测试** - 使用 React Testing Library 测试 React 组件 - **集成测试** - 用于插件交互 - **E2E 测试** - 使用 Playwright 测试关键用户流程 测试必须: - 提交前通过 - 覆盖边界情况和错误状态 - 遵循 Arrange-Act-Assert 模式 - 使用中文或英文的描述性测试名称 ### CSS/SCSS 标准 遵循 BEM 方法论: ```scss .component-name { // 1. Position position: relative; // 2. Box model width: 100%; padding: 16px; // 3. Appearance background: var(--color-bg); border-radius: 8px; // 4. Typography font-size: 14px; // 5. Animation transition: all 0.2s ease-out; // 6. Nested elements &__header { } &__content { } // 7. Modifiers &--active { } // 8. Responsive @media (max-width: 768px) { } } ``` ## Git 与版本控制 ### 提交信息格式 遵循 Conventional Commits: ``` ():