Regression / regression (push) Canceled after 0s
本提交含两条并行工作线,因互相咬合(package.json scripts、regression.yml、 npm run build 链)无法按文件干净拆分,故合并为一次自洽提交。 ## 详情页减重(本轮主任务:修复「AI 干太重」) - 导航收敛:宽屏只用右侧目录、≤1200px 只用页内 sticky 导航,纯 CSS 媒体查询 实现(不引入 JS 宽度监听)。此前两套导航同时可见,active 状态互相打架。 - 入口去重:标题区由「查看示例/在线测试/契约 JSON」三个减为「在线测试」一个; 契约 JSON 归入实现资源;删除示例底部重复的「在线测试」。 - 示例工具栏:删除与目录锚点重复的示例下拉选择器;「全部展开代码」只在 示例数 >1 时出现(103 个组件里 49 个仅 1 个示例,此前恒显示)。 - 重复文案:示例区两句同义导语合并为一句。 - 首页 CTA 由 5 个减为 2 个(浏览组件/快速开始),测试总览入口挂到已有的 通过率统计卡上,不再另占 Hero 按钮。 - 统一详情取数:抽出 fetchDetail/loadDetail 作为 details/*.json 的唯一路径, FAQ 不再自行 fetch 一遍,与组件页共用缓存与失败兜底。 ## i18n - 删除 12 组重复键(含整段 FAQ 说明),字典 604 → 585 唯一键。 - 删除本次改动产生的 6 个死键。 - verify-i18n.mjs 新增 `unique dictionary keys` 断言:重复键在对象字面量里 是静默的后值覆盖,此前无从发现;现由门禁拦住。 ## 文档事实修正(实测为准) - TESTING/CONTRIBUTING:79 → 103 组件;旧断言数改为回指 tests/report.json。 - PLATFORMS:移动端 108 文件/18 端 → 282 文件/47 端;契约 5 → 47; 令牌 17 → 15;uni-app SFC 21 → 50。 - AGENTS:断言 1405/18 页 → 1464/103 页(PC)、807/47 页(移动端)。 - package.json:YOUR-ACCOUNT 占位 → gitea 实址与 kole-ui.mymoyu.top。 ## 品牌标识(并行会话成果,一并入库) - brand-mark.json 收归真源,build:brand 生成 favicon 与单色 SVG; PC 与移动端共用资产,verify:brand 24 条断言。 - regression.yml 增加 verify:brand 步骤。 ## 门禁与验收 新增工具:verify-component-page.mjs(86 条真实浏览器断言,随详情页改造同步 更新为「只允许一套导航可见」)、verify-brand-mark.mjs、lib/i18n-dead-keys.mjs (只读诊断)。 回归:PC 100%(1464/1464,103 页,N/A 50)· 移动端 100%(807/807,47 页)。 门禁:component-page 86 · i18n 17 · brand 24 · routes all · smoke all · theme OK · isolation 31 · nav all · examples 9 · api-docs 10 · mobile-docs 12。 已知未做:i18n 另有约 44 条历史死键(非本次产生),已记为 ROADMAP S8-P6; 顶栏与悬浮区的两个主题入口为刻意设计(verify-theme 断言其互斥),未删。
353 lines
26 KiB
Markdown
353 lines
26 KiB
Markdown
# AGENTS.md · Kole UI 执行约定
|
||
|
||
> **给在此仓库工作的 AI 模型**:这个文件是硬约束,不是建议。开始任何任务前先读完。
|
||
> 人类贡献者请看 [CONTRIBUTING.md](./CONTRIBUTING.md);任务清单看 [ROADMAP.md](./ROADMAP.md)。
|
||
|
||
---
|
||
|
||
## 一 · 这个仓库是什么
|
||
|
||
**Kole UI Design System** —— B 端中后台设计系统,**两个平台 × 六个端**(详见 [PLATFORMS.md](./PLATFORMS.md)):
|
||
|
||
- **PC 平台**:103 个中后台组件 × 5 端(H5 原生 / React / Vue 2 / Vue 3 / CSS)
|
||
- **移动端平台**:触屏优先组件 × 6 端(上述 5 端 + **uni-app**),与 PC 物理隔离
|
||
- **PC × uni-app 端**:把 PC 组件清单以 uni-app 实现(试点 3 / 103)
|
||
|
||
| 项 | 值 |
|
||
|---|---|
|
||
| PC 组件 | 103 |
|
||
| PC 端实现文件 | 515(`frameworks/`,103 × 5) |
|
||
| PC 契约 JSON | 103(`.design_library/kole-ui/components/`) |
|
||
| 设计令牌 | 75(`colors_and_type.css`)+ 移动端 15(`--kole-m-*`,@import PC 令牌) |
|
||
| i18n 字典 | 592 条(`site/i18n.js`;`verify:i18n` 卡重复键为 0) |
|
||
| PC 测试断言 | 1464 通过 / N/A 50(`tests/`,103 页;共 1514 条) |
|
||
| **移动端组件** | **47**(导航 6 · 反馈 12 · 通用 5 · 数据展示 8 · 数据录入 16) |
|
||
| **移动端端实现文件** | **282**(`frameworks-mobile/`,47 × 6 端) |
|
||
| **移动端测试断言** | **807 通过 / N/A 10**(`tests/mobile/`,47 页;共 817 条) |
|
||
| **PC × uni-app 试点** | **3**(`frameworks-uniapp-pc/`,button / input / card) |
|
||
| 回归通过率 | **PC 100%(八次连跑一致)· 移动端 100%** |
|
||
|
||
**新增组件/端之前先读 [PLATFORMS.md](./PLATFORMS.md)** —— 那里有两轴模型、目录命名映射、新增流程与隔离规则。
|
||
|
||
---
|
||
|
||
## 二 · 六条铁律(违反即返工)
|
||
|
||
### 1. 零运行时依赖
|
||
|
||
不引入 npm **运行时**依赖。
|
||
|
||
```bash
|
||
# 验收:这条必须在所有改动后通过
|
||
# 注意:P2 之前 package.json 不存在,此时应输出 "n/a (no package.json yet)" 而非报错
|
||
node -e "
|
||
const fs=require('fs');
|
||
if(!fs.existsSync('package.json')) { console.log('n/a (no package.json yet)'); process.exit(0) }
|
||
const p=require('./package.json');
|
||
const deps=Object.keys(p.dependencies||{});
|
||
if(deps.length) { console.error('FAIL: 运行时依赖 ' + deps.join(', ')); process.exit(1) }
|
||
console.log('zero-dep OK');
|
||
"
|
||
```
|
||
|
||
`devDependencies` 可用(构建/测试工具),但要在 README 注明"CI 专用"。
|
||
|
||
### 2. `build-site.ps1` 必须 ASCII-only
|
||
|
||
PowerShell 5.1 按 ANSI 读无 BOM 文件 —— 脚本里出现非 ASCII 字面量会被**静默损坏**。
|
||
|
||
- 中文文案放 UTF-8 模板(`tests/_template.html` 等)
|
||
- 输出用 `[System.IO.File]::WriteAllText($path, $content, [System.Text.UTF8Encoding]::new($false))` 写无 BOM
|
||
- `build-site.ps1` 只能在 Windows 跑;CI 需要构建时改用 `runs-on: windows-latest`
|
||
|
||
#### 构建链是两步,必须按序执行
|
||
|
||
```bash
|
||
npm run build:site # 等价于下面两步
|
||
# 1) powershell -NoProfile -ExecutionPolicy Bypass -File build-site.ps1
|
||
# 2) node tools/precompute.mjs
|
||
```
|
||
|
||
**第 2 步不能省** —— `build-site.ps1` 会把 `data.js` 重写回全量(2026-09-20 实测 1166 KB),
|
||
`tools/precompute.mjs` 才做瘦身(同次实测 → 122 KB,把 css 源码移到 `site/sources/<slug>/css.txt`)。
|
||
只跑第 1 步会导致:`data.js` 变大、且 `sourcesRef` 字段消失 → 详情页代码区缺 CSS tab。
|
||
|
||
单独重跑只需 `npm run precompute`。
|
||
|
||
### 3. 改结构要改模板
|
||
|
||
`tests/<slug>.html` × 103 是**生成物**。改它们没用 —— 下次重跑会被覆盖。
|
||
|
||
| 想改 | 改哪里 |
|
||
|---|---|
|
||
| 测试页结构 | `tests/_template.html` → 重跑 `run-tests.ps1` |
|
||
| 测试总览页 | `tests/_index_template.html` |
|
||
| 测试断言逻辑 | `tests/_runtime.js`(跨帧断言引擎) |
|
||
| 文档站 | `site/app.js` |
|
||
|
||
### 4. 改样式要改内嵌层
|
||
|
||
**演示页的内嵌 `<style>` 才是实际生效的样式。**
|
||
|
||
v1.4.0 的教训:花了几小时令牌化 `frameworks/*.css`(915 处),结果发现演示页不一定 link 它 —— 真正生效的是内嵌的 `<style>` 块(另 287 处)。
|
||
|
||
```bash
|
||
# 诊断:这个页面的样式从哪来
|
||
grep -o 'href="[^"]*\.css"' frameworks/Button.html
|
||
# 若无 frameworks/Button.css,说明样式在内嵌 <style> 里
|
||
```
|
||
|
||
### 5. `data.json` 是对外承诺
|
||
|
||
`site/data.json` 是对外承诺的「一次请求拿到全部」(原先由文档站的 For Agents 页公示,该页已于 2026-09-20 随 AI 消费模块一并移除,承诺本身不变)。可以拆 `data.js`(性能优化),但 **`data.json` 必须保持完整**。
|
||
|
||
破坏它是 breaking change。
|
||
|
||
### 6. 单次改动后必须跑回归
|
||
|
||
```bash
|
||
node site/dev-server.js & # 起服务(端口 3311)
|
||
# 浏览器打开 http://127.0.0.1:3311/tests/_collect.html
|
||
# 或:node tools/run-regression.mjs(需 playwright)
|
||
```
|
||
|
||
**验收标准**:`100% / 0 失败 / 0 超时`,且**连跑八次一致**。
|
||
|
||
> 为什么是八次:偶发问题(并发超时)在单次运行中可能不出现。项目的超时兜底逻辑已改为「重试一次 + 超时单列」,但连跑仍是最可靠的验证。
|
||
|
||
---
|
||
|
||
## 三 · 禁止事项
|
||
|
||
| 禁止 | 原因 | 正确做法 |
|
||
|---|---|---|
|
||
| 手工改 `frameworks/` 里的样式让它"更好看" | 那是规范原文的忠实实现 | 改令牌,或走 ROADMAP 任务包 |
|
||
| 把移动端组件放进 `frameworks/`,或在移动端实现里用 PC 的类名/令牌 | 两端目录、类名(`kole-` vs `kole-m-`)、令牌(`--kole-` vs `--kole-m-`)是隔离边界;混放后 PC 的目录数、测试数、分发产物全会被污染 | 移动端一律写 `frameworks-mobile/`,见 PLATFORMS.md §一/§二;`npm run verify:isolation` 会拦 |
|
||
| 在 uni-app 端使用 `document` / `window` / `PointerEvent` / `rpx`(PC 列) | 小程序与 App 端没有 DOM,也没有 PointerEvent;`rpx` 是移动端语义 | 用 uni 基础组件 + `@touch*` 事件;移动列用 `rpx`、PC 列用 `px`;`npm run verify:uniapp` 会拦 |
|
||
| 直接改 PC 的 `site/data.json` / `tests/report.json` 来"顺便"容纳移动端数据 | 这两个是 PC 侧的对外承诺与证据 | 移动端另起 `site/m/data.mobile.json` / `tests/mobile-report.json` |
|
||
| `git reset --hard` / `git checkout .` 清理 | 会丢用户改动 | `git stash` 或定向还原 |
|
||
| 改写 `CHANGELOG.md` 的历史条目 | 变更事实记录 | 只追加 `[Unreleased]` 或新版本段 |
|
||
| 改 `tests/report.json` 的数值 | 等于伪造证据 | 修实际问题后重跑生成 |
|
||
| 为通过验收而放宽断言判据 | v1.3.1 出现过这个诱惑 | 判据修正必须附**理由 + 反例** |
|
||
| 在任务范围外顺手重构 | 范围蔓延让验收失焦 | 写成新任务包追加到 ROADMAP |
|
||
|
||
---
|
||
|
||
## 四 · 交付形态
|
||
|
||
每个任务完成时提交**交付说明**:
|
||
|
||
```markdown
|
||
## <任务 ID> 完成说明
|
||
|
||
**验收输出**(原样粘贴命令输出,不要转述):
|
||
(命令 + 输出)
|
||
|
||
**改动文件**:
|
||
- <路径> — <做了什么>
|
||
|
||
**规划偏差**(若有):
|
||
- ROADMAP 写的 <X> → 实际的 <Y>,原因:<...>
|
||
|
||
**发现的新问题**(若有):
|
||
- <描述> → 已追加为 ROADMAP 任务包 <ID>
|
||
|
||
**回归**:100%(<通过>/<总数>)/ 八次连跑一致 / 0 超时
|
||
```
|
||
|
||
**不要写「已完成」而不给证据。** 这个项目的历史上有 6 次"文档声称完成但代码缺失",全部是靠实测发现的。
|
||
|
||
---
|
||
|
||
## 五 · 失败升级路径
|
||
|
||
按顺序处理,**不要停下来等**:
|
||
|
||
| 情况 | 处理 |
|
||
|---|---|
|
||
| 验收命令本身有错 | 修正它使其真实反映目标,在交付说明写明修了什么、为什么 |
|
||
| 目标不可达(依赖的服务/网络不可用) | 交付最强替代物 + 写明缺什么 |
|
||
| 发现 ROADMAP 有事实错误 | **以实测为准**,修正规划并标注「⚠️ 规划修正」 |
|
||
| 发现规划未覆盖的新缺口 | 写成新任务包追加到 ROADMAP,**不在原任务里顺手修** |
|
||
| 同一路径连续两次失败 | 换策略而非重试,记录两次失败的原因 |
|
||
|
||
---
|
||
|
||
## 六 · 关键文件地图
|
||
|
||
```
|
||
组件规范第一套/
|
||
├─ AGENTS.md ← 本文件(硬约束)
|
||
├─ PLATFORMS.md ← 平台 × 端两轴模型 + 隔离规则(新增组件/端前必读)
|
||
├─ ROADMAP.md ← 任务清单(任务包 + 验收命令)
|
||
├─ CHANGELOG.md ← 变更记录(build 时注入文档站)
|
||
├─ CONTRIBUTING.md ← 人类贡献指南
|
||
├─ TESTING.md ← 测试矩阵说明
|
||
├─ LICENSE ← MIT
|
||
│
|
||
├─ build-site.ps1 ← PC 文档站构建(ASCII-only!生成 data.js/data.json/薄壳/sitemap/令牌导出)
|
||
├─ run-tests.ps1 ← 重生成 103 个 PC 测试页
|
||
│
|
||
├─ frameworks/ ← PC:515 个实现文件(103 × 5 端)—— 只读,除非规格变更
|
||
├─ frameworks-mobile/ ← 移动端:282 个实现文件(47 × 6 端,含 .uniapp.vue)
|
||
├─ frameworks-uniapp-pc/ ← PC × uni-app 端:3 个试点 SFC
|
||
│
|
||
├─ .design_library/kole-ui/ ← PC 设计库
|
||
│ ├─ colors_and_type.css ← 75 个设计令牌(改色的唯一入口,两端共用)
|
||
│ ├─ components.css ← 6 核心组件样式聚合
|
||
│ ├─ css.json ← 结构化令牌(For Agents 消费)
|
||
│ ├─ components/*.json ← 103 份契约(含 unknowns/doNotInvent)
|
||
│ └─ specs/组件1~10.txt ← 规范原文(CRLF!读时用 split(/\r?\n/))
|
||
│
|
||
├─ .design_library/kole-ui-mobile/ ← 移动端设计库(与 PC 隔离)
|
||
│ ├─ colors_and_type.css ← @import PC 令牌 + 15 个 --kole-m-* 触控/安全区令牌
|
||
│ ├─ components/index.json ← 移动端索引(6 端声明 + 隔离规则)
|
||
│ ├─ components/*.json ← 5 份契约(sourceKind: authored-spec)
|
||
│ └─ spec/移动端规格.md ← 移动端规格原文(契约的授权来源,**无外部规范**)
|
||
├─ .design_library/kole-ui-uniapp/index.json ← PC × uni-app 索引(试点 3 / 103)
|
||
│
|
||
├─ site/
|
||
│ ├─ app.js ← PC 文档站全部逻辑(History API 路由 SPA)
|
||
│ ├─ index.html ← SPA 壳:内联脚本按 URL 反推站点根,资源用绝对地址写出
|
||
│ ├─ i18n.js ← 330 条中英字典(中文源串作键)
|
||
│ ├─ data.js / data.json ← PC 构建产物(勿手改;data.json 是对外承诺)
|
||
│ ├─ examples/<slug>.json ← 逐示例用法片段(构建期生成,按组件懒加载)
|
||
│ │ 一个使用场景 = 标题 + 预览隐藏计划 + 四端调用代码,
|
||
│ │ 出处标注 demo-mapped / demo-data / api-derived(见 tools/lib/demo-examples.mjs)
|
||
│ ├─ tokens/ ← 令牌导出(CSS / W3C DTCG / Figma)
|
||
│ ├─ components/*.html ← 103 个静态薄壳(SEO 入口)
|
||
│ └─ m/ ← 移动端文档站(静态页,不进 PC 路由表)
|
||
│ ├─ style.css ← 自包含样式(不引 site/style.css)
|
||
│ ├─ _index_template.html ← 总览页模板(改结构改这里)
|
||
│ ├─ _guide_template.html ← 快速开始(三步接入 / 6 端示例 / 常见问题)
|
||
│ ├─ _platform_template.html ← 平台与端(两轴矩阵 / 映射表 / 隔离规则 / 门禁命令)
|
||
│ ├─ _tokens_template.html ← 设计令牌(--kole-m-* 表 + 继承令牌表)
|
||
│ ├─ _component_template.html ← 组件页模板(14 小节,改结构改这里)
|
||
│ ├─ index/guide/design/faq/changelog/platform.html ← 生成物(六页:与 PC 同名同序的指南页)
|
||
│ ├─ data.mobile.json ← 移动端自包含数据(18 × 6 端源码,生成物)
|
||
│ └─ component/<slug>.html ← 逐组件文档页(生成物:API / 6 端源码 / 令牌 / 回归状态)
|
||
│
|
||
└─ tests/
|
||
├─ _template.html ← PC 测试页模板(改结构改这里)
|
||
├─ _runtime.js ← 跨帧断言引擎(**两端共用**)
|
||
├─ _behaviors.js ← PC 行为库(6 试点组件)
|
||
├─ _collect.html ← PC 零依赖批量回归收集器
|
||
├─ report.json ← PC 回归报告(生成物)
|
||
├─ <slug>.html × 103 ← PC 生成物
|
||
└─ mobile/ ← 移动端测试
|
||
├─ _template.html ← 移动端测试页模板(375×640 设备帧)
|
||
├─ _behaviors.js ← 移动端行为库(含 swipe-sets-class / swipe-sets-attr / pull-triggers)
|
||
├─ _collect.html ← 移动端收集器(读 site/m/data.mobile.json)
|
||
└─ <slug>.html × 5 ← 生成物(tests/mobile-report.json 为移动端回归报告)
|
||
```
|
||
|
||
**构建与门禁脚本(移动端相关)**:`tools/build-mobile.mjs`(移动端全部产物:数据 / 文档站四页 + 组件页 / 测试页 / `dist/mobile/**`;写入守卫只允许 `site/m/` `tests/mobile/` `dist/mobile/`)、`tools/build-uniapp.mjs`(PC×uni-app 产物,守卫只允许 `dist/uniapp-pc/`)、`tools/verify-mobile-isolation.mjs`(30 条隔离断言:PC 零污染 / 移动端自洽 / 分发隔离)、`tools/verify-uniapp.mjs`(9 条 uni-app 静态断言 × 21 个 SFC)、`tools/verify-uniapp-build.mjs`(11 条**真实编译**断言:隔离目录装 @dcloudio → 搭最小工程 → 21 个 SFC 编译到 H5 + mp-weixin → 断言产物含契约声明的类名)、`tools/verify-mobile-docs.mjs`(12 条文档完整性断言:14 小节齐全 / 侧栏列全 / **契约 API ↔ 4 个框架端源码逐名一致** / 变体类名在 CSS 里真实存在)、`tools/verify-mobile-site.mjs`(118 条浏览器实测:200 / 0 控制台错误 / 演示帧真渲染 / 令牌生效 / 320–768px 无横向溢出)、`tools/run-mobile-regression.mjs`(移动端回归,报告含逐页 `pageResults`)。
|
||
|
||
**逐示例用法片段(`npm run verify:examples`)**:`tools/lib/demo-examples.mjs` 在构建期做三件事 —— 切场景(`extractExamples`)、提 class↔prop 映射(`extractClassPropMap`)、生成四端用法片段(`buildSnippets`);`tools/verify-examples.mjs` 复核落地产物(片段里的 prop 必须能指到 API/源码、class 必须在组件 CSS 里、预览隐藏路径必须能解析到 demo 页 DOM)。**判据只认「能指到源码某处」的事实**,不做启发式打分。
|
||
|
||
---
|
||
|
||
## 七 · 已知陷阱速查
|
||
|
||
| 陷阱 | 现象 | 解法 |
|
||
|---|---|---|
|
||
| 规范文件是 CRLF | 正则 `/^#{3}/` 匹配不到行尾,标题解析全失败 | `split(/\r?\n/)` 先归一化 |
|
||
| PS5.1 写文件带 BOM | 严格 JSON 解析器(node require)直接失败 | `WriteAllText` + `UTF8Encoding($false)` |
|
||
| 演示页 DOM 由内联脚本生成 | 静态抽快照得到空 DOM | 用 iframe 载真实页面跨帧断言 |
|
||
| 并发 iframe 抢主线程 | 偶发超时被误记为失败 | 已修:超时重试 + 超时单列(见 `_collect.html`) |
|
||
| 深层路由刷新 404 | `/site/component/button/h5` 磁盘上没有这个文件,只有前端能渲染 | 三处回落缺一不可:`nginx.conf` 的 `location /site/`、`site/dev-server.js` 的 `isSpaRoute`、Pages 发布包的 `404.html`;`tools/verify-site-routing.mjs` 会静态卡这四处 |
|
||
| 站点目录改名 / SPA 壳里写相对路径 | 深层 URL 下相对路径全部按深层目录解析(CSS 与 `data.js` 静默 404) | 站点根从 `pathname` 里第一段 `/site/` 反推(`site/index.html` 内联脚本 + `app.js` 的 `SITE_BASE` 两处,必须同规则);资源一律 `base + 'xxx'` 绝对地址写出 —— 静态相对路径会被预扫描器按深层 URL 先白取一次(实测 2 个 404 + 2 条控制台报错,`data.js` 整份重下) |
|
||
| 改令牌组件不变 | 改的是没被加载的文件 | 改内嵌 `<style>`(铁律 4) |
|
||
| 逐示例代码区**常显**后主题对比度门禁变红 | 代码块借 `--kole-color-tooltip-bg`,该令牌暗色下是**浅色**(tooltip 反色),而代码文字与语法高亮是固定浅色 → 浅压浅;此前代码区默认收起、`verify-theme` 的对比度抽查扫不到,改成常显后立刻暴露 | 深色下给代码区补 `html.kole-dark .ex-code { background: var(--kole-color-page-bg) }`;语法高亮调色板按深底实测选(`hl-tag` 8.24 / `hl-kw` 7.35:1 等,全部 ≥4.5:1)。**新增常显代码块时同步跑 `npm run verify:theme`** |
|
||
| 演示页脚本钩子 `id` 混进用法代码 | 例:`<button class="btn" id="demo-toggle">` 里的 id 是演示脚本 `getElementById` 用的钩子,用户复制后无用且误导 | 构建期用 `extractDemoIds()` 收集脚本引用过的 id,`buildSnippets` 里剔除;同理 `data-behavior`/`data-assert` 是测试钩子,一律不进片段 |
|
||
| `$themes` / `$schema` 在 PS 里 | 被当变量展开成 null,报"Null 键" | 用引号包裹键名 `'$themes'` |
|
||
| `Write-Output "...{}..." -f $n` | `{}` 被当格式占位符 | 改写措辞或转义 |
|
||
| `.dockerignore` 的 `*.md` / `*.png` 等 glob | **只匹配构建上下文根目录**,嵌套路径照样进镜像(实测:`sub/nested.md` 仍被 COPY) | 嵌套一律写 `**/*.md`;排除目录写完整相对路径 |
|
||
| 手工拷贝部署目录 | 修复被下一次拷贝覆盖(`absolute_redirect off` 就是这样丢的),且 .dockerignore 不随行导致规范原文入镜像 | 走 §九 的 `tools/pack-deploy.mjs`,不要手工拷贝 |
|
||
| 部署后浏览器仍跑旧 JS | 静态资源无 `Cache-Control` 时浏览器会启发式缓存(实测:页面内 `fetch` 能取到新 `app.js`,`<script src>` 却用缓存) | nginx 已加 `Cache-Control: no-cache`(带 ETag 复验 304);**升级前遗留的旧缓存需强刷一次** |
|
||
| `KOLE_PORT` 默认 13311 与文档里的隧道端口撞车 | `tools/verify-dev-server.mjs` 报 `EADDRINUSE` 并失败 | 隧道开着时用 `KOLE_PORT=13511 node tools/verify-dev-server.mjs` |
|
||
| 新增类名 / 令牌 / 组件导出名时随手起前缀 | 这三类前缀都是**品牌缩写**,不是任意命名:类 `kole-`、令牌 `--kole-`、导出名 `Kole*`(如 `KoleButton`)。v2.0.0 起统一;此前是 `aa-` + Input 组件的 `au-`,导出名是 `Aa*` | 新增一律沿用 `kole-` / `--kole-` / `Kole*`;批量改名或查残留用 `tools/migrate-brand-kole-ui.mjs`(`--dry-run` 预演 / `--verify` 扫残留)。**补规则时用 `--only=<子串>`**:全量重跑会把「刻意记录旧名」的对照表(本表、CHANGELOG 2.0.0 段)也改写掉 |
|
||
| 把「对外实测事实」当成品牌词一起批量替换 | 例:`aurora-admin-design 未被占用`(当时实测)被改成 `kole-ui 未被占用` —— 事实变成未核验断言(v2.0.0 改名时真的踩到) | 品牌词可替换,**记录了外部状态的名字只能新增核验**:还原旧名 + 补一次新名的实测并写明日期 |
|
||
| 新增顶层目录后忘了加进 dev-server 白名单 | 页面在浏览器里 **403**(`frameworks-mobile/NavBar.html` 实测),但直接用相对路径打开文件是好的,容易误判成"构建没产出" | `site/dev-server.js` 的 `PUBLIC_ROOTS` + `isPublicPath()` **两处**都要加(本次新增 `frameworks-mobile`、`frameworks-uniapp-pc`);nginx 走 `location /` 全放行,不需要改 |
|
||
| 本地 3311 上还挂着**改动前**启动的 dev-server | 新目录一律 403 / 新页面 404,日志里是 `EADDRINUSE`(新实例根本没起来),而老实例照常服务旧代码 | `site/dev-server.js` 已改为**端口占用自动回退**(最多 10 档)并在启动时打印全部入口(PC 站 / 移动端站 / 两个测试总览 / 两个收集器);要固定端口用 `KOLE_PORT=13511 node site/dev-server.js`,再用 `REG_BASE=http://127.0.0.1:<实际端口>` 跑回归与门禁 |
|
||
| 顶栏 UI 改动后忘了同步「按文字量计算」的验证脚本 | `verify-nav-responsive.mjs` 的字体容忍度元素清单仍指向已不存在的 `.fw-label`,余量被报得偏乐观(少算一个元素) | 改顶栏文字承载元素时同步该清单(本次 `.fw-label`/`#fw-select` → `.fw-cur`/`.fw-menu .fw-opt`);判据不放松,只是让测量对象跟着 UI 走 |
|
||
| 同一页并列展示多个 `position: fixed` 的移动端组件 | 全部叠在视口同一位置,演示页"看起来只渲染了一个" | 展示框加 `transform: translateZ(0)`(或任何 transform/filter)建立包含块,`fixed` 就以该框为基准;本次 TabBar / ActionSheet 演示页用此法,组件 CSS 保持 `fixed` 不变 |
|
||
| 静态门禁把**注释**当成违规代码 | 「注释里解释为什么不用 PointerEvent」被判成 `PointerEvent` 违规(本次 3 个文件误报);`\brpx\b` 也匹配不到 `100rpx`(`0` 与 `r` 之间没有词边界) | 门禁先剥注释(`<!-- -->`、`/* */`、**行首** `//`)再判;单位判据写 `[0-9]rpx\b`。判据修正的理由已写进 `tools/verify-uniapp.mjs` 注释 |
|
||
|
||
---
|
||
|
||
## 八 · 当前状态
|
||
|
||
**版本**:v1.0.0 | **回归**:PC 100%(1464 通过 / 0 失败 / N/A 50,共 1514 条断言,103 页)· 移动端 100%(807 通过 / 0 失败 / N/A 10,共 817 条,47 页)| **下一阶段**:ROADMAP 的 S7 移动端批次
|
||
|
||
**已完成的里程碑**:
|
||
- v1.3.0 验收链路修复(测试页从空 DOM 误报改为 iframe 真实渲染)
|
||
- v1.3.1 无障碍与令牌合规(回归 85.1% → 100%)
|
||
- v1.3.2 契约全量 79/79 + 令牌导出三格式
|
||
- v1.3.3 中英双语 i18n
|
||
- v1.4.0 组件层全面令牌化(1202 处)
|
||
- v1.4.1 四轮审计 + 回归偶发根治
|
||
- v2.0.0 品牌重命名 Kole UI(1373 文件 / 约 2.9 万处;类名前缀 `aa-`+`au-` → `kole-`,令牌 `--au-` → `--kole-`,包名 `kole-ui`,破坏性变更)
|
||
|
||
**当前缺口(详见 ROADMAP 的 G1-G8)**:
|
||
无 LICENSE(已补)、无分发机制、CI 无测试、暗色模式是假的、跨端一致性无验证、`data.js` 1MB、RTL 未支持、断言偏结构。
|
||
|
||
---
|
||
|
||
## 九 · 部署(192.168.5.7)
|
||
|
||
**当前形态**(2026-09-20 实测):容器 `kole-ui-showcase` / 镜像 `kole-ui-showcase:latest`,端口 `127.0.0.1:3311 -> 80`。
|
||
**只监听回环**——局域网直连 `192.168.5.7:3311` 会超时,这是有意的;**公网入口是 `https://kole-ui.mymoyu.top`**(经服务器上的 frp 隧道指向同一容器),所以除 SSH 隧道外还有这一条公网访问路径。不要靠改绑定或挂反代来解决"打不开"。
|
||
|
||
**本机访问(Windows,已实测可用)**:
|
||
|
||
```bash
|
||
ssh -o ExitOnForwardFailure=yes -N -L 13311:127.0.0.1:3311 root@192.168.5.7
|
||
# 然后浏览器打开 http://127.0.0.1:13311/site/
|
||
```
|
||
|
||
本地用 13311 而不是 3311,是为了不和 `node site/dev-server.js`(本地也占 3311)抢端口。
|
||
**想要局域网/其它设备直接访问**:那是一次显式的暴露变更(改 compose 绑定为 `0.0.0.0:3311`),并且 Docker 发布端口会绕过 ufw 规则 —— 需要明确许可后再做。
|
||
|
||
**部署目录**:`/opt/aurora-admin`(= docker build 上下文,必须含 `Dockerfile` / `nginx.conf` / `.dockerignore` / `docker-compose.yml` / `sitemap.xml` + 4 个内容目录)。目录名仍是改名前的,容器/镜像已随仓库切到 `kole-ui-showcase` —— 刻意不重命名目录,`mv` 同名替换即可,避免动 compose 项目标识。
|
||
|
||
**标准流程**(不要在服务器上手工拼文件):
|
||
|
||
```bash
|
||
# 1) 本地打包(.dockerignore 是排除规则的唯一真源,含硬断言)
|
||
# 先带公网基址构建:不带 SITE_URL_BASE 时 build-site.ps1 会把 sitemap 写成占位域名
|
||
# (tools/release.mjs 的既有约定是「占位禁正式发布」)。
|
||
SITE_URL_BASE=https://kole-ui.mymoyu.top/ npm run build:site
|
||
node tools/pack-deploy.mjs --tar # -> dist-deploy/kole-ui-deploy.tar.gz
|
||
|
||
# 2) 上传 + 备份现状
|
||
# scp 到 /tmp/kole-ui-deploy.tar.gz
|
||
# ssh: tar czf /root/kole-ui-backup-$(date +%Y%m%d-%H%M).tgz -C /opt aurora-admin
|
||
# 同时给现役镜像打回滚标签:docker tag kole-ui-showcase:latest kole-ui-showcase:pre-<日期>
|
||
|
||
# 3) 解到暂存目录、核对、替换、重建
|
||
cd /opt && mkdir -p aurora-admin.staged \
|
||
&& tar xzf /tmp/kole-ui-deploy.tar.gz -C aurora-admin.staged --strip-components=1
|
||
ls -a aurora-admin.staged # 必须无 specs/ agent-reports/ preview/ ui_kits/
|
||
# 逐字节核对(包内哈希取自本地 `find dist-deploy/kole-ui -type f -exec sha256sum {} +`)
|
||
# 远端:cd /opt/aurora-admin.staged && find . -type f -exec sha256sum {} + | sort -k2
|
||
# 两边路径前缀归一后 diff,必须 0 行差异
|
||
mv aurora-admin aurora-admin.prev-<日期> && mv aurora-admin.staged aurora-admin
|
||
cd /opt/aurora-admin && docker compose build && docker compose up -d
|
||
|
||
# 4) 验收(五条必须全中)
|
||
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3311/.design_library/kole-ui/specs/ # 404(目录级;单文件请求也是 404)
|
||
curl -sI http://127.0.0.1:3311/ | grep -i '^Location' # /site/
|
||
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3311/sitemap.xml # 200
|
||
curl -sI http://127.0.0.1:3311/healthz | grep -ci '^content-type' # 1
|
||
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3311/site/component/button/h5 # 200(SPA 深层路由)
|
||
# 版本核对
|
||
curl -s http://127.0.0.1:3311/site/data.json | grep -o '"version": *"[^"]*"' | head -1 # 期望当前版本
|
||
```
|
||
|
||
**部署前必读**:
|
||
- 本工作区**可能有并发构建/审计任务在写 `site/`、`frameworks/`**。打包前后各查一次产物哈希:若打包后又被改写,线上快照就落后于源码——要么等稳定后重发,要么在交付说明里写明。2026-09-20 本轮部署中真的踩到(`app.js` 在打包后 1 分钟被改过)。
|
||
- `REG_BASE` 不设置时 `tools/run-regression.mjs` 打的是 `http://127.0.0.1:3311`——**隧道开着时那就是线上旧版**,会给出"回归 100%"的假绿灯。验证本地构建请先 `KOLE_PORT=3399 node site/dev-server.js`,再 `REG_BASE=http://127.0.0.1:3399 node tools/run-regression.mjs`。
|
||
|
||
**铁律**:任何"只改服务器、不回写仓库"的修复都会在下次部署时丢失——`nginx.conf` 的 `absolute_redirect off` 已经因此丢过一次。先改仓库,再走打包流程。
|