0de9b6e66e
- core/table-core: Headless 表格内核(排序/筛选/分页/选择插件 + 冒烟 9 项) - core/frame: signal/computed/effect + hyperscript 微框架(零依赖) - skin/ui: 16 个 DOM 组件(含自绘 select、滑动指示条 tabs、行选择 dataTable、form 表单校验) - design/tokens: --ua-* 设计令牌(light/dark) - tools/cli: ua 命令行(index/list/info/docs/style/mcp)+ MCP 注册表服务 - apps: demo 演示站(esbuild 单文件)+ docs 双轨文档(人类版 + llms-full.txt)
70 lines
4.1 KiB
Markdown
70 lines
4.1 KiB
Markdown
# CODING.md — 个人编码规范(固定资产)
|
||
|
||
> 适用于本仓库所有 TS / JS 代码。人与 Agent 共同遵守,改代码前先读此文件。
|
||
|
||
## 1. 注释规范(强制)
|
||
|
||
- **强制写注释**:所有导出函数、接口 / 类型、非平凡内部函数必须有注释;无注释的导出视为未完成。
|
||
- **语言**:注释一律中文(标识符、命令、路径除外)。
|
||
- **函数级**:`/*** 作用 ***/` 置于函数 / 方法上方,一句话讲清"做什么",必要时补一句"返回什么";不复述签名、不写废话。
|
||
- **类型 / 接口**:`/*** 用途 ***/` 单行置于上方。
|
||
- **逐字段**:接口 / 类型别名每个字段都在行尾跟一句 `// 注释`,包括联合类型的每个分支。
|
||
- **行级**:其他说明用 `// 短注释` 写在行尾,只解释"为什么"或标注关键分支意图;禁止流水账、禁止翻译代码。
|
||
|
||
```ts
|
||
/*** 值比较:数值按大小、其余按字符串序,null 恒排末尾 ***/
|
||
function compareValues(a: unknown, b: unknown): number {
|
||
if (a == null) return 1; // 卫语句:空值排后
|
||
if (typeof a === 'number') return a - (b as number);
|
||
return String(a).localeCompare(String(b));
|
||
}
|
||
|
||
/*** 一条排序规则 ***/
|
||
export interface SortRule {
|
||
key: string; // 排序字段,对应 ColumnDef.key
|
||
dir: 'asc' | 'desc'; // 排序方向
|
||
}
|
||
```
|
||
|
||
## 2. 类型工程化
|
||
|
||
- **与项目平行**:类型集中放在与源码目录平行的类型文件(如 `src/types.ts`),与实现文件镜像对应;类型不散落在实现文件里。
|
||
- **紧凑**:每行一个字段(或一个联合分支),不留空行;简单接口可整体单行。
|
||
- **逐字段注释**:见上,字段注释写清"是什么、什么语义、缺省行为"。
|
||
- **命名一致**:`*Options`(入参)/ `*State`(状态)/ `*Plugin`(插件)/ `*Info`(派生快照),同类东西同名后缀,方便统一改动。
|
||
|
||
## 3. 变量与状态声明
|
||
|
||
- **集中顶部、显式声明**:模块级 / 闭包级状态(缓存、计数器、句柄)集中在作用域顶部声明;函数内变量也尽量集中顶部。
|
||
- 仅单个分支内部使用的临时变量允许就近声明,但禁止跨分支复用"就近变量"。
|
||
- 禁止隐式全局、禁止"用到才顺手声明"的散落写法——统一管理的前提是声明可一眼盘点。
|
||
|
||
```ts
|
||
let lastInput: RowModel | null = null; // memo:上一次输入
|
||
let lastRules: SortRule[] | null = null; // memo:上一次排序切片
|
||
let cached: RowModel | null = null; // memo:缓存产物
|
||
```
|
||
|
||
## 4. 代码风格
|
||
|
||
- **紧凑 + 行工整**:能一行写清就一行;同构代码块(平行赋值、字段表)纵向对齐。
|
||
- **卫语句单行**:`if (!x) return;` 提前返回;嵌套超过两层必须提前返回或提取小函数。
|
||
- **可读性优先**:命名直白(见名知意),不炫技;三目只用于纯取值,复杂条件先提具名变量。
|
||
|
||
## 5. 低侵入与派生一致性
|
||
|
||
- **低侵入**:新能力一律以插件 / 钩子 / 可选参数接入,不改核心签名、不动既有调用方;扩展字段必须可选,破坏性变更走新版本而非就地修改。
|
||
- **派生语义一致**:派生量只从上游单一来源推导,命名与上游字段对齐(如 `RowModel.total` 在整条管线中始终表示"筛选后、分页前的行数");禁止旁路重复计算同一派生量,保证"改一处、全局一致"。
|
||
- 派生链路顺序固定并写进注释(如 filter → sort → paginate),谁改变语义谁负责同步所有下游注释与文档。
|
||
|
||
## 6. 架构取向
|
||
|
||
- **高可扩展是核心**:扩展点 = 插件 / 钩子 / 数据管线,而不是继承层级。
|
||
- **低复杂度、低抽象**:不为"将来可能"预先抽象;同一模式出现第二次再提取。
|
||
- **单文件尽量 < 200 行**:超出先拆职责,不拆"层"。
|
||
|
||
## 7. 落地方式
|
||
|
||
- 新代码必须符合本规范;旧代码顺手迁移,不强制一次性全量重写。
|
||
- 后续可做成 `ua style` 检查项:导出缺注释、接口字段缺注释、类型散落实现文件、闭包状态未集中顶部。
|