1031 lines
46 KiB
Markdown
1031 lines
46 KiB
Markdown
# Aurora Admin · 长期路线图与任务包
|
||
|
||
> **文档性质**:交给执行模型的工程规划。每个任务包自带验收命令与失败判据,拿到即可开工,不需要再问。
|
||
> **基线版本**:v1.4.1(2026-09-11)
|
||
> **规划人**:海鸥(规划师角色)
|
||
> **更新约定**:任务完成时在本文件对应任务包下追加 `✅ 完成于 <commit>`,不要删原计划。
|
||
|
||
---
|
||
|
||
## 〇 · 交接约定(执行模型必读)
|
||
|
||
### 0.1 铁律(违反即返工)
|
||
|
||
1. **零运行时依赖不可破**:不引入 npm 运行时依赖。构建/测试脚本用 Node 内置能力或 PowerShell。`package.json` 的 `dependencies` 必须为空(`devDependencies` 可用)。
|
||
2. **`build-site.ps1` 必须 ASCII-only**:PS5.1 按 ANSI 读无 BOM 文件,脚本里出现非 ASCII 字面量会被损坏。中文文案放 UTF-8 模板。
|
||
3. **改结构要改模板**:`tests/<slug>.html` 是生成物 —— 改它没用。改 `tests/_template.html` / `tests/_index_template.html` 后重跑 `run-tests.ps1`。
|
||
4. **改样式要改内嵌层**:演示页的**内嵌 `<style>`** 才是实际生效的样式(v1.4.0 教训:只改 `frameworks/*.css` 可能不生效,因为演示页不一定 link 它)。
|
||
5. **`data.json` 是 For Agents 的对外承诺**:可以拆 `data.js`,但 `data.json` 必须保持完整(一次请求拿到全部)。破坏它是 breaking change。
|
||
6. **单次改动后必须跑回归**:`tests/_collect.html` 八次连跑,`100% / 0 失败 / 0 超时` 才算过。
|
||
|
||
### 0.2 禁止事项(做过即需回滚)
|
||
|
||
| 禁止 | 原因 | 正确做法 |
|
||
|---|---|---|
|
||
| 在 `frameworks/` 里直接手工改出"更好看"的样式 | `frameworks/` 是规范原文的忠实实现,改动会破坏契约一致性 | 要改样式先改令牌,或走任务包流程 |
|
||
| 用 `git reset --hard` / `git checkout .` 清理 | 会丢用户改动 | 用 `git stash` 或定向还原 |
|
||
| 删除或改写 `CHANGELOG.md` 的历史条目 | 那是变更事实记录 | 只追加 `[Unreleased]` 或新版本段 |
|
||
| 修改 `tests/report.json` 的数值来"通过"验收 | 报告是生成物,改它等于伪造证据 | 修实际问题后重跑生成 |
|
||
| 为了通过验收而放宽断言判据 | v1.3.1 曾出现"调松断言刷分"的诱惑 | 断言判据的修正必须附**理由 + 反例** |
|
||
| 在规划未涉及的领域顺手重构 | 范围蔓延会让验收失焦 | 写成新任务包追加到本文件 |
|
||
|
||
### 0.3 环境与工具
|
||
|
||
| 项 | 说明 |
|
||
|---|---|
|
||
| 操作系统 | Windows(开发)/ Linux(CI)。跨平台写法见下方「跨平台注意」 |
|
||
| Shell | Git Bash(开发)/ bash(CI) |
|
||
| Node | ≥ 18(用到 `node:sqlite` 的任务需 ≥ 22) |
|
||
| 构建 | `powershell -NoProfile -ExecutionPolicy Bypass -File build-site.ps1`(**Windows 专用**) |
|
||
| 回归 | 浏览器打开 `tests/_collect.html`,或 `node tools/run-regression.mjs`(需 playwright) |
|
||
| 本地服务 | `node site/dev-server.js`(端口 3311) |
|
||
|
||
**跨平台注意**:
|
||
- 后台启动服务:Windows Git Bash 用 `node site/dev-server.js &`,CI 用 `node site/dev-server.js & sleep 3`。**不要用 `start` 或 `nohup`**。
|
||
- 路径分隔符:脚本里统一用 POSIX 风格(`/`),Node 的 `path` 模块会处理。
|
||
- PowerShell 脚本**只能在 Windows 跑**。若 CI 需要构建,改写为 Node 脚本或加 `runs-on: windows-latest`。
|
||
|
||
### 0.4 失败升级路径
|
||
|
||
执行中遇到阻塞时,按这个顺序处理,**不要停下来等**:
|
||
|
||
| 情况 | 处理 |
|
||
|---|---|
|
||
| 验收命令本身有错(路径不对、语法不兼容) | 修正命令使其能真实反映目标,**在交付说明里写明修正了什么、为什么** |
|
||
| 目标不可达(如依赖的服务/网络不可用) | 交付最强替代物 + 写明缺什么。例:无法 `npm pack` 则做本地 `npm pack --dry-run` 的等价检查 |
|
||
| 发现规划有事实错误(如"某字段占 89%"实际不是) | **以实测为准**,修正规划并在本文件标注「⚠️ 规划修正」 |
|
||
| 发现规划未覆盖的新缺口 | 写成新任务包追加到本文件,**不在原任务里顺手修** |
|
||
| 连续两次尝试同一路径都失败 | 换策略而非重试。在交付说明里记录两次失败的原因 |
|
||
|
||
### 0.5 交付说明模板(每个任务包完成时提交)
|
||
|
||
```markdown
|
||
## <任务 ID> 完成说明
|
||
|
||
**验收输出**(原样粘贴命令输出,不要转述):
|
||
```
|
||
<命令>
|
||
<输出>
|
||
```
|
||
|
||
**改动文件**:
|
||
- <路径> — <做了什么>
|
||
|
||
**规划偏差**(若有):
|
||
- <规划里写的> → <实际的>,原因:<...>
|
||
|
||
**发现的新问题**(若有):
|
||
- <描述> → 已追加为任务包 <ID>
|
||
|
||
**回归**:100%(<总断言>/<通过>)/ 八次连跑一致 / 0 超时
|
||
```
|
||
|
||
---
|
||
|
||
## 一 · 现状基线(全部为实测数据)
|
||
|
||
### 1.1 资产规模
|
||
|
||
| 项 | 数量 | 测量方式 |
|
||
|---|---|---|
|
||
| 组件 | 79 | `components/index.json` |
|
||
| 5 端实现文件 | 395 | `ls frameworks/*.{html,css,jsx,vue2.vue,vue3.vue}` 各 79 |
|
||
| 契约 JSON | 79(全量) | `ls .design_library/aurora-admin/components/*.json` |
|
||
| 契约 usageHints | 358 条 | 遍历契约累加 |
|
||
| 契约 unknowns | 139 条 | 同上(**现成的 FAQ 素材**) |
|
||
| 契约 doNotInvent | 101 条 | 同上 |
|
||
| 设计令牌 | 75 个 | `site/data.json` → `tokens.length` |
|
||
| i18n 字典 | 330 条 | `site/i18n.js` |
|
||
| 测试断言 | 961 条(12.2/页) | `tests/report.json` |
|
||
| 文档站路由 | 9 个 | home/overview/guide/design/changelog/agents/component/scenario/tests |
|
||
|
||
### 1.2 质量指标
|
||
|
||
| 项 | 值 | 说明 |
|
||
|---|---|---|
|
||
| 回归通过率 | **100%** | 八次连跑一致,0 失败 0 超时 |
|
||
| N/A 断言 | 36(3.7%) | 静态组件无交互面、单实例组件无多变体,已逐条核实 |
|
||
| 契约保真度 | 93.9% 逐字命中规格 | 余 22 条为同义改写,非发明 |
|
||
| 令牌语义错配 | 0 / 1313 处 | 属性与令牌角色全部匹配 |
|
||
| i18n 质量 | 0 残留中文、0 未翻译 | 326 条字典 |
|
||
| 组件可换肤 | 79/79 | 逐组件改令牌比对样式签名 |
|
||
|
||
### 1.3 性能基线
|
||
|
||
| 指标 | 值 | 说明 |
|
||
|---|---|---|
|
||
| 文档站传输量 | **1247 KB** | 7 个资源 |
|
||
| 其中 `data.js` | **1058 KB(85%)** | ← 最大优化目标 |
|
||
| `app.js` | 101 KB | 未压缩 |
|
||
| `style.css` | 40 KB | 未压缩 |
|
||
| DOMContentLoaded | 345 ms | 本地 dev-server,线上更慢 |
|
||
| 每详情页额外 | iframe 1 个 | 加载对应演示页 |
|
||
|
||
### 1.4 实测缺口(按严重度)
|
||
|
||
| # | 缺口 | 实测证据 | 影响 |
|
||
|---|---|---|---|
|
||
| **G1** | **无 LICENSE** | `ls LICENSE` → 不存在 | 法律上不可用,对外交付的硬阻塞 |
|
||
| **G2** | **无分发机制** | 无 `package.json` / 无 CDN / 无发布流程 | 用户拿不到,只能 clone 仓库 |
|
||
| **G3** | **CI 无测试** | `.github/workflows/` 只有 `deploy-pages.yml` | 回归靠手动,质量无持续保障 |
|
||
| **G4** | **暗色模式是假的** | 令牌层 `aa-dark` 规则 **0** 条、组件层 **0** 条、仅站点骨架 **7** 条 | CHANGELOG 曾称"补全",实为第 6 次声称≠实现 |
|
||
| **G5** | **跨端一致性无验证** | 5 端 395 文件,无任何自动比对 | H5/React/Vue2/Vue3 视觉是否一致**无从知晓** |
|
||
| **G6** | **`data.js` 1MB** | 占传输量 85% | 首屏慢,移动端更差 |
|
||
| **G7** | **RTL 未支持** | 逻辑属性 0 处 / 物理属性 22 文件 | 阿拉伯语等市场不可用 |
|
||
| **G8** | **断言偏结构** | 12 项/页,多为"元素存在",无"点击后发生什么" | 行为回归无覆盖 |
|
||
|
||
---
|
||
|
||
## 二 · 长期愿景与阶段划分
|
||
|
||
### 2.1 目标状态(12 个月)
|
||
|
||
> **一句话**:从「一个做得很完整的组件库仓库」,变成「一个能被外部团队直接采用的设计系统产品」。
|
||
|
||
拆成四个可验证的终态:
|
||
|
||
1. **可交付** —— 有许可证、有分发渠道、有 CI 保障,外部团队 5 分钟内能用上。
|
||
2. **可信** —— 关键声称(暗色、跨端一致、无障碍)全部有自动化证据,不靠文档承诺。
|
||
3. **完整** —— 覆盖国际化(含 RTL)、无障碍实测、性能预算。
|
||
4. **生态** —— 设计工具链打通(Figma)、典型页面可直接复用、有版本发布节奏。
|
||
|
||
### 2.2 阶段划分与决策依据
|
||
|
||
| 阶段 | 主题 | 解决 | 决策依据 |
|
||
|---|---|---|---|
|
||
| **S1** | 可交付 | G1 G2 G3 G6 | 前三个是**对外交付的硬阻塞**:没许可证不能商用,没分发拿不到,没 CI 质量会退化。G6 顺手做(data.js 占 85% 传输量,收益最大) |
|
||
| **S2** | 可信 | G4 G5 G8 | 都是「声称了但没证据」。G4 是第 6 次声称≠实现,必须先止血 |
|
||
| **S3** | 完整 | G7 + 无障碍实测 | RTL 与无障碍是竞品 7 家里的分水岭(3 家有 RTL) |
|
||
| **S4** | 生态 | Figma/模板/发布 | 前两阶段完成后,生态建设才有意义 |
|
||
|
||
**为什么这个顺序**:S1 是"能不能用",S2 是"能不能信",S3 是"够不够全",S4 是"好不好用"。顺序颠倒会做出没人敢用的产品。
|
||
|
||
---
|
||
|
||
## 三 · 任务包
|
||
|
||
> 格式:**目标 → 依据 → 依赖 → 路径 → 步骤 → 验收 → 失败判据**
|
||
> 每个任务包独立可执行,除标注依赖外互不阻塞。
|
||
|
||
---
|
||
|
||
### S1-P1 · LICENSE 许可证 | 预算 ~10 min | 优先级 P0
|
||
|
||
**目标**:仓库根目录存在 `LICENSE`,明确授权范围,移除对外交付的法律阻塞。
|
||
|
||
**依据**:G1。`CONTRIBUTING.md` 与 `README.md` 都在讲如何贡献与使用,但没有许可证意味着**默认保留所有权利**,外部团队法务不会放行。
|
||
|
||
**依赖**:无。需用户确认许可证类型(见下方决策点)。
|
||
|
||
**路径**:`LICENSE`(新建)
|
||
|
||
**步骤**:
|
||
1. 确认许可证类型。若用户未指定,**默认 MIT**(与本项目"零依赖、鼓励复用"的定位一致),并在交付说明里标注"如需变更请告知"。
|
||
2. 写入标准 MIT 全文,版权行为 `Copyright (c) 2026 Aurora Admin`。
|
||
3. 在 `README.md` 增加 `## 许可证` 段,链接到 `LICENSE`。
|
||
4. 在 `CHANGELOG.md` 的 `[Unreleased]` 下追加 `### Added — LICENSE`。
|
||
|
||
**验收**:
|
||
```bash
|
||
# 文件存在且包含关键条款
|
||
test -f LICENSE && grep -q "MIT License" LICENSE && grep -q "WITHOUT WARRANTY" LICENSE && echo "LICENSE OK"
|
||
|
||
# README 有链接
|
||
grep -q "LICENSE" README.md && echo "README OK"
|
||
```
|
||
|
||
**预期输出**:
|
||
```
|
||
LICENSE OK
|
||
README OK
|
||
```
|
||
|
||
**失败判据**:任一条命令无输出,或 `LICENSE` 里出现非标准条款(自行增删免责声明)。
|
||
|
||
**决策点(需用户输入)**:许可证类型。MIT 是默认推荐;若项目未来要商业化或要求衍生作品开源,应改 Apache-2.0 或 MPL-2.0。
|
||
|
||
**✅ 完成(MIT,采用默认选择)** — 验收输出:
|
||
|
||
```
|
||
LICENSE OK
|
||
README OK
|
||
```
|
||
|
||
同步改动:`LICENSE`(MIT 全文)、`README.md`(新增「许可证」段 + 版本号更新为 v1.4.1 + 指向本路线图)。
|
||
如需改为 Apache-2.0 / MPL-2.0:替换 `LICENSE` 全文,同步 `README.md` 与未来 `package.json` 的 `license` 字段即可,无其他联动。
|
||
|
||
---
|
||
|
||
### S1-P2 · npm 分发 | 预算 ~2 h | 优先级 P0
|
||
|
||
**目标**:`npm install aurora-admin-design` 能拿到令牌 + 组件样式;`<link>` 可直接引 CDN。
|
||
|
||
**依据**:G2。当前用户只能 clone 整个仓库(5.1MB git + 2.6MB site),对"只想用几个组件"的人成本过高。
|
||
|
||
**前置验证已完成**(规划阶段实测):
|
||
|
||
| 假设 | 结果 |
|
||
|---|---|
|
||
| npm 可用 | ✅ v11.17.0 |
|
||
| 包名 `aurora-admin-design` 是否被占用 | ✅ **未被占用**(registry 返回 `{"error":"Not found"}`) |
|
||
| `colors_and_type.css` 可否直接作 dist 令牌源 | ✅ 含 `:root`、75 个令牌,可直接用 |
|
||
| 零依赖约束下能否构建 dist | ✅ Node 内置能力足够(读写文件 + JSON) |
|
||
|
||
**依赖**:S1-P1(package.json 需声明 `license` 字段)。
|
||
|
||
**路径**:
|
||
- `package.json`(新建)
|
||
- `.npmignore`(新建)
|
||
- `tools/build-dist.mjs`(新建,产出分发产物)
|
||
- `dist/`(构建产物,加入 `.gitignore`)
|
||
|
||
**步骤**:
|
||
1. 建 `package.json`,关键字段:
|
||
```json
|
||
{
|
||
"name": "aurora-admin-design",
|
||
"version": "1.4.1",
|
||
"description": "B 端中后台设计系统 · 79 组件 × 5 端 · 零运行时依赖",
|
||
"license": "MIT",
|
||
"main": "dist/tokens/tokens.css",
|
||
"files": ["dist/", "README.md", "LICENSE"],
|
||
"scripts": {
|
||
"build": "node tools/build-dist.mjs",
|
||
"test": "node tools/verify-dist.mjs"
|
||
},
|
||
"keywords": ["design-system", "admin", "css-variables", "design-tokens"],
|
||
"sideEffects": ["*.css"]
|
||
}
|
||
```
|
||
**注意:不声明任何 `dependencies`** —— 这是硬约束。
|
||
2. 写 `tools/build-dist.mjs`(Node ESM,零依赖),产出:
|
||
- `dist/tokens/tokens.css`、`tokens.json`(复用 `build-site.ps1` 的产出)
|
||
- `dist/components/<slug>.css` × 79 + `dist/components/index.css`(聚合)
|
||
- `dist/components/<slug>.html` × 79(静态演示)
|
||
- `dist/README.md`(用法速查,从主 README 节选)
|
||
- `dist/manifest.json`(组件清单 + 版本 + 文件校验和)
|
||
3. 写 `.npmignore` 排除 `site/`、`tests/`、`frameworks/*.jsx|vue*`、`.github/`、`*.png`。
|
||
4. 在 `README.md` 增加「安装」段,给出 npm / CDN / 直接下载三种方式。
|
||
|
||
**验收**:
|
||
```bash
|
||
# 1) 构建产物齐全
|
||
node tools/build-dist.mjs
|
||
test -f dist/tokens/tokens.css && echo "tokens OK"
|
||
test -f dist/components/index.css && echo "aggregate OK"
|
||
test $(ls dist/components/*.css | wc -l) -ge 80 && echo "79 components + index OK"
|
||
|
||
# 2) 无运行时依赖(硬约束)
|
||
node -e "const p=require('./package.json'); if(p.dependencies) { console.error('FAIL: 不允许 dependencies'); process.exit(1) } console.log('zero-dep OK')"
|
||
|
||
# 3) 分发内容不含开发资产
|
||
# 注意:不能用 `npm pack | grep -q site/ && echo FAIL || echo OK` —— npm 不可用时 grep 也失败,会误报 OK
|
||
if npm pack --dry-run >/tmp/pack.txt 2>&1; then
|
||
if grep -qE "site/|tests/" /tmp/pack.txt; then
|
||
echo "FAIL: 打包含开发资产"; grep -E "site/|tests/" /tmp/pack.txt | head -3; exit 1
|
||
fi
|
||
echo "pack contents OK"
|
||
else
|
||
echo "SKIP: npm 不可用(网络/未安装),此项需在有 npm 的环境补验"
|
||
fi
|
||
|
||
# 4) 产物可用(起本地服务,浏览器打开验证)
|
||
node -e "const fs=require('fs');const c=fs.readFileSync('dist/components/index.css','utf8');if(!c.includes('--au-color-brand'))process.exit(1);console.log('css usable OK')"
|
||
```
|
||
|
||
**预期输出**:
|
||
```
|
||
tokens OK
|
||
aggregate OK
|
||
79 components + index OK
|
||
zero-dep OK
|
||
pack contents OK
|
||
css usable OK
|
||
```
|
||
|
||
**失败判据**:
|
||
- `package.json` 出现任何 `dependencies`
|
||
- `npm pack --dry-run` 输出含 `site/` 或 `tests/`
|
||
- `dist/components/*.css` 少于 80 个
|
||
|
||
**已知风险**:`npm pack` 需要网络(首次可能要求登录)。若无网络,跳过第 3 条验收并在交付说明注明。
|
||
|
||
---
|
||
|
||
### S1-P3 · CI 回归流水线 | 预算 ~1.5 h | 优先级 P0
|
||
|
||
**目标**:每次 push/PR 自动跑回归,失败则阻止合并;结果可在 GitHub Actions 页面看到。
|
||
|
||
**依据**:G3。当前只有部署 workflow,回归靠人工手动跑 `_collect.html`,质量随提交退化不可见。
|
||
|
||
**依赖**:无(可与 P1/P2 并行)。
|
||
|
||
**路径**:
|
||
- `.github/workflows/regression.yml`(新建)
|
||
- `tools/run-regression.mjs`(**已存在**,需改造为无网可用)
|
||
|
||
**步骤**:
|
||
1. 现状:`tools/run-regression.mjs` 依赖 `playwright`(npm 包),与"零依赖"约束冲突。
|
||
**解法**:CI 里允许用 `npx playwright`(CI 环境的临时工具,不进 `package.json` 的 dependencies),或用 `devDependencies` + 在文档说明"CI 专用,运行时不依赖"。
|
||
**推荐**:把 playwright 放进 `devDependencies`(这是构建期工具,不违反"零运行时依赖")。
|
||
2. 写 workflow:
|
||
```yaml
|
||
name: Regression
|
||
on: [push, pull_request]
|
||
jobs:
|
||
test:
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
- uses: actions/setup-node@v4
|
||
with: { node-version: '20' }
|
||
- run: npm i -D playwright && npx playwright install --with-deps chromium
|
||
- run: node site/dev-server.js &
|
||
- run: sleep 3
|
||
- run: node tools/run-regression.mjs
|
||
- uses: actions/upload-artifact@v4
|
||
if: always()
|
||
with: { name: regression-report, path: tests/report*.json }
|
||
```
|
||
3. `run-regression.mjs` 需改造:目前是纯 Node 脚本,要确保它在 Linux 下也能找到报告输出路径(Windows 路径分隔符问题)。
|
||
4. 增加失败阈值:`passRate < 100` 时 `process.exit(1)`。
|
||
|
||
**验收**:
|
||
```bash
|
||
# 本地模拟 CI 步骤
|
||
node site/dev-server.js & sleep 3
|
||
node tools/run-regression.mjs
|
||
echo "exit=$?"
|
||
# 期望 exit=0 且 passRate=100
|
||
```
|
||
推送后在 GitHub Actions 页面确认 workflow 跑绿(需用户操作)。
|
||
|
||
**预期输出**:
|
||
```
|
||
passRate 100% | pages 79 (all-pass 79) | assertions 925/925
|
||
written: tests/report.json, tests/report-junit.xml
|
||
exit=0
|
||
```
|
||
|
||
**失败判据**:
|
||
- workflow 文件语法错误(用 `actionlint` 或 GitHub 页面报错验证)
|
||
- 本地模拟跑出 `exit != 0`
|
||
- `passRate < 100` 时没有 `exit 1`
|
||
|
||
**已知风险**:`playwright install` 在 CI 上约需 1-2 分钟,可通过缓存加速(后续优化项)。
|
||
|
||
---
|
||
|
||
### S1-P4 · `data.js` 瘦身 | 预算 ~3 h | 优先级 P0
|
||
|
||
**目标**:`site/data.js` 从 **991 KB 降到 < 150 KB**(实测可达成 ~110 KB)。
|
||
|
||
**依据**:G6。实测 `data.js` = 1058 KB(传输量),占文档站总传输 **85%**。
|
||
|
||
**已完成的诊断(无需重做)**:
|
||
|
||
```
|
||
data.json 体积构成(实测)
|
||
总计: 991KB
|
||
components 974KB 98.3% ← 唯一大头
|
||
changelog 12KB 1.2%
|
||
tokens 5KB 0.5%
|
||
|
||
components[] 内部(单组件)
|
||
.sources 15.7KB ← 5 端源码全文
|
||
.contract 0.8KB
|
||
.specLines 0.2KB
|
||
.files 0.2KB
|
||
其余 <0.1KB
|
||
|
||
全部组件 .sources 合计: 888KB(占 data.json 的 89.6%)
|
||
```
|
||
|
||
**结论**:`sources` 字段(5 端源码全文,仅供详情页代码区展示)占了 **89.6%**。把它移出 `data.js` 改为按需 fetch,`data.js` 降到 **~110 KB**(−89%)。
|
||
|
||
**依赖**:无。
|
||
|
||
**路径**:
|
||
- `build-site.ps1`(改造产出:分文件写源码)
|
||
- `site/app.js`(改造消费:按需 fetch + loading 态)
|
||
- `site/sources/<slug>/<kind>.txt`(新增产出目录,79 × 5 = 395 个文件)
|
||
- `site/data.js` / `site/data.json`(产出物,不手改)
|
||
|
||
**步骤**:
|
||
1. **改造 `build-site.ps1`**:
|
||
- 新增:把每个组件的 5 端源码写到 `site/sources/<slug>/<kind>.txt`(kind ∈ html/css/jsx/vue2/vue3)
|
||
- 修改:`data.js` 里 `components[].sources` 改为 `sourcesRef: "sources/<slug>/"`(只留路径,不留内容)
|
||
- **保持 `data.json` 完整**(For Agents 页承诺"一次请求拿到全部",不能破坏 —— 这是硬约束)
|
||
2. **改造 `app.js`(见下方「已完成的依赖分析」)**
|
||
3. **验证 For Agents 承诺未破**:`data.json` 仍然包含完整 `sources`。
|
||
|
||
##### 已完成的依赖分析(执行前必读)
|
||
|
||
`app.js` 里有 **10 处**消费 `c.sources`,分三类,改造难度不同:
|
||
|
||
**类别 A · 渲染期同步解析(难点,2 处)**
|
||
|
||
| 位置 | 函数 | 用途 |
|
||
|---|---|---|
|
||
| `app.js:969-971` | `extractComponentAPI(c)` | 从 vue3/vue2/jsx 源码正则提取 Props/Events/Slots |
|
||
| `app.js:1544` | `extractScenarios(c)` | 从 html 源码提取 `<h2>` 场景标题 |
|
||
|
||
这两个函数**在渲染详情页时同步调用**,依赖源码字符串立即可用。改成 fetch 后必须处理异步。
|
||
|
||
**推荐解法**:把「源码解析」的产物**预计算进 data.js**,而不是运行时 fetch 后再解析。
|
||
|
||
- `build-site.ps1` 已经能读源码 → 顺手把 `extractComponentAPI` / `extractScenarios` 的**结果**写进 `data.js`
|
||
- `app.js` 改为直接读预计算结果,**这两个函数不再需要源码**
|
||
- 源码 fetch 只服务「代码展示」这一处需求
|
||
|
||
**体积成本已实测**(规划阶段验证过):
|
||
|
||
```
|
||
API 表(79 组件) : 0.2 KB
|
||
场景标题(79 组件) : 0.9 KB
|
||
合计新增 : 1.0 KB
|
||
sources 移除后节省 : 888 KB
|
||
净减少 : 887 KB
|
||
```
|
||
|
||
预计算产物只占 **1 KB**(原估 < 30KB,实测乐观 30 倍),代价可忽略。
|
||
|
||
这样做的好处:① 消除两处异步改造;② 解析逻辑从浏览器移到构建期(更快);③ 详情页首屏不再等源码下载。
|
||
|
||
**类别 B · 代码展示(3 处,易改)**
|
||
|
||
| 位置 | 用途 |
|
||
|---|---|
|
||
| `app.js:1635` | Playground textarea 初值 |
|
||
| `app.js:1667` | Playground 复位 |
|
||
| `app.js:1714/1722` | 代码区高亮渲染 |
|
||
|
||
改法:进详情页时 `Promise.all` 拉当前组件 5 个源码文件(或按需拉 tab 切换的那一个),拿到后填充。加 loading 占位。
|
||
|
||
**类别 C · 判断可用性(2 处,用元数据替代)**
|
||
|
||
| 位置 | 用途 |
|
||
|---|---|
|
||
| `app.js:1703-1704` | 判断哪些端有源码(决定 tab 显示) |
|
||
| `app.js:1720` | 复制按钮取当前 tab 源码 |
|
||
|
||
改法:`data.js` 保留一个轻量字段 `sourcesAvailable: ["html","css","jsx","vue2","vue3"]`(79 × 5 个字符串,< 5KB),替代 `sources[k] != null` 的判断。复制按钮改为从已缓存的 fetch 结果取。
|
||
|
||
##### 分阶段执行建议
|
||
|
||
1. **阶段 1**:`build-site.ps1` 预计算 API/场景 → 写入 `data.js`;`app.js` 改读预计算结果。此时 `sources` 仍完整(先不瘦身),跑回归确认无回退。
|
||
2. **阶段 2**:`build-site.ps1` 分离源码到文件 + `data.js` 只留 `sourcesRef` 与 `sourcesAvailable`;`app.js` 改 fetch。
|
||
3. **阶段 3**:跑验收 + 浏览器实测(含断网兜底)。
|
||
|
||
**验收**:
|
||
```bash
|
||
# 1) 体积达标(实测应约 110KB)
|
||
node -e "
|
||
const fs=require('fs');
|
||
const core=fs.statSync('site/data.js').size;
|
||
console.log('data.js:', (core/1024).toFixed(0)+'KB');
|
||
if(core/1024 > 150) { console.error('FAIL: 超过 150KB 预算'); process.exit(1) }
|
||
console.log('budget OK');
|
||
"
|
||
|
||
# 2) 源码文件已分离(395 个)
|
||
# 注意:目录未创建时 ls 会报错到 stderr,这里显式兜底,让输出可读
|
||
n=$(ls site/sources/*/*.txt 2>/dev/null | wc -l)
|
||
echo "sources files: $n (期望 395)"
|
||
if [ "$n" -ne 395 ]; then
|
||
echo "FAIL: 期望 395 个源码文件,实际 $n"
|
||
echo " 提示:若目录不存在,说明 build-site.ps1 的分离逻辑未执行"
|
||
exit 1
|
||
fi
|
||
echo "split OK"
|
||
|
||
# 3) data.json 未缩水(For Agents 承诺不变 —— 硬约束)
|
||
node -e "
|
||
const d=require('./site/data.json');
|
||
const c=d.components.find(x=>x.slug==='button');
|
||
if(!c.sources||Object.keys(c.sources).length!==5) { console.error('FAIL: data.json 的 sources 被破坏'); process.exit(1) }
|
||
console.log('data.json intact OK');
|
||
"
|
||
|
||
# 4) data.js 里已无源码正文
|
||
node -e "
|
||
const d=require('./site/data.js')||{};
|
||
" 2>/dev/null || node -e "
|
||
const fs=require('fs');
|
||
const s=fs.readFileSync('site/data.js','utf8');
|
||
// 源码正文特征:不应再出现完整 HTML 文档
|
||
if(s.includes('<!DOCTYPE html>')) { console.error('FAIL: data.js 仍含源码正文'); process.exit(1) }
|
||
console.log('sources removed OK');
|
||
"
|
||
```
|
||
浏览器实测:
|
||
- 打开 `#/component/button`,代码演示区正常显示
|
||
- Network 面板出现 `sources/button/html.txt` 请求
|
||
- 断网/404 情况下显示兜底提示而非空白
|
||
|
||
**预期输出**:
|
||
```
|
||
data.js: ~110KB
|
||
budget OK
|
||
sources files: 395
|
||
split OK
|
||
data.json intact OK
|
||
sources removed OK
|
||
```
|
||
|
||
**失败判据**:
|
||
- `data.js` > 150 KB
|
||
- `site/sources/` 文件数 ≠ 395
|
||
- **`data.json` 的 `sources` 字段被动过**(会破坏 For Agents 承诺)
|
||
- 详情页代码区空白或报错
|
||
|
||
**为什么不直接压缩**:gzip 能压到 ~200KB,但**解析时间**与**内存占用**仍在(1MB JSON 在低端机解析约 100-200ms)。且 Pages 默认已开 gzip,压缩不是增量收益。根治要减体积。
|
||
|
||
---
|
||
|
||
### S1-P4b · 首屏资源优化 | 预算 ~2 h | 优先级 P1
|
||
|
||
**目标**:文档站首屏传输从 1247 KB 降到 **< 300 KB**。
|
||
|
||
**依据**:P4 完成后 `data.js` ~110KB,但 `app.js` 101KB + `style.css` 40KB 仍是未压缩文本。
|
||
|
||
**依赖**:S1-P4。
|
||
|
||
**步骤**:
|
||
1. `app.js`(101KB 单文件)按路由拆分:首页逻辑与详情页逻辑分离,详情页按需加载。
|
||
2. 关键 CSS 内联(首屏可见部分),其余异步加载。
|
||
3. 加入 `build-site.ps1` 的产出:`.min.js` / `.min.css`(用 Node 内置能力做简单压缩:去注释、去多余空白)。
|
||
|
||
**验收**:
|
||
```bash
|
||
node -e "
|
||
const fs=require('fs');
|
||
const files=['site/data.js','site/app.js','site/style.css','site/i18n.js','.design_library/aurora-admin/colors_and_type.css'];
|
||
const total=files.reduce((s,f)=>s+fs.statSync(f).size,0);
|
||
console.log('首屏资源合计:', (total/1024).toFixed(0)+'KB');
|
||
if(total/1024>300){console.error('FAIL: 超过 300KB');process.exit(1)}
|
||
console.log('payload OK');
|
||
"
|
||
```
|
||
|
||
---
|
||
|
||
### S2-P5 · 暗色模式真正实现 | 预算 ~1 天 | 优先级 P0
|
||
|
||
**目标**:`html.aa-dark` 下,**79 个组件的演示页**全部正常反色,对比度仍满足 WCAG AA。
|
||
|
||
**依据**:G4。实测令牌层 `aa-dark` 规则 **0 条**、组件层 **0 条**,只有站点骨架 7 条。`CHANGELOG.md` 的 v1.1.1 条目称"暗色模式令牌映射补全"—— 这是第 6 次声称≠实现。
|
||
|
||
**依赖**:S1-P4(体积优化后改 `app.js` 更清爽,非硬依赖)。
|
||
|
||
**路径**:
|
||
- `.design_library/aurora-admin/colors_and_type.css`(加暗色令牌组)
|
||
- `site/style.css`(清理原有的 7 条临时规则)
|
||
- `frameworks/*.html` 的内嵌样式(若需微调)
|
||
- `tests/_runtime.js`(增加暗色断言)
|
||
|
||
**步骤**:
|
||
1. **设计暗色令牌组**(在 `colors_and_type.css` 里加 `html.aa-dark` 块):
|
||
- 背景层:`page-bg` `#14161C` → `card-bg` `#1C1F26` → `table-header-bg` `#22262E`(三层递进)
|
||
- 文字层:`text-title` `#E8EAED` → `text-body` `#C9CDD4` → `text-secondary` `#9CA3AF` → `text-placeholder` `#6B7280`
|
||
- 边框:`border` `#2A2F38`、`border-strong` `#363B45`
|
||
- 品牌色:**向白提亮**(`#2F54EB` 在深底上对比度不足),推荐 `#5B7CF5` 系列
|
||
- 语义色:同样提亮(`#2E7D0A` → `#4CAF50` 一类)
|
||
2. **每个色值都要算对比度**,写脚本验证(复用 v1.3.1 的方法):
|
||
```bash
|
||
node -e "
|
||
// 对每个暗色令牌算 WCAG 对比度,全部 ≥4.5:1(文字)或 ≥3:1(图标)
|
||
"
|
||
```
|
||
3. **演示页反色策略**:v1.4.0 的注释说"演示 iframe 保持浅色,避免样例反色失真"。这条策略要么:
|
||
- **A**:改成可配置 —— 站点暗色时演示页也反色(更真实,但要确保反色后不难看)
|
||
- **B**:保持浅色,但在设计规范页显式说明这是**有意设计**
|
||
**推荐 A**,因为用户开暗色就是想整体变暗,局部刺眼是体验倒退。若选 A,需给演示页传 `?theme=dark` 或用 `postMessage` 通知。
|
||
4. **加断言**:`_runtime.js` 增加 `matrix:dark-contrast`,在暗色令牌下重跑对比度检查。
|
||
|
||
**验收**:
|
||
```bash
|
||
# 1) 令牌组存在且完整
|
||
grep -q "html.aa-dark" .design_library/aurora-admin/colors_and_type.css && echo "dark tokens OK"
|
||
node -e "
|
||
const css=require('fs').readFileSync('.design_library/aurora-admin/colors_and_type.css','utf8');
|
||
const m=css.match(/html\.aa-dark\s*\{([^}]+)\}/s);
|
||
if(!m){console.error('FAIL: 无暗色令牌组');process.exit(1)}
|
||
const n=(m[1].match(/--au-/g)||[]).length;
|
||
console.log('暗色令牌数:', n);
|
||
if(n<15){console.error('FAIL: 令牌数不足(预期 ≥15)');process.exit(1)}
|
||
"
|
||
|
||
# 2) 浏览器实测(关键验收)
|
||
# 打开 http://127.0.0.1:3311/site/index.html,切暗色模式,
|
||
# 逐个打开至少 10 个组件详情页,确认无「白底黑字残留」
|
||
```
|
||
浏览器实测项:
|
||
- 首页 / 总览 / 设计规范 / 组件详情 全部正常反色
|
||
- 任意 10 个组件演示页反色后**对比度可读**
|
||
- 截图对比(交付说明附 3 张暗色截图)
|
||
|
||
**预期输出**:
|
||
```
|
||
dark tokens OK
|
||
暗色令牌数: 20+(预期 ≥15)
|
||
```
|
||
|
||
**失败判据**:
|
||
- 暗色令牌数 < 15
|
||
- 任一页面出现"白底 + 白字"或"黑底 + 黑字"
|
||
- 对比度脚本报出 < 4.5:1 的文字
|
||
|
||
**已知风险**:79 个演示页的内嵌样式是**硬编码过令牌化**的(v1.4.0 完成),所以理论上改令牌就能全局生效 —— 这是 v1.4.0 打下的地基,本次直接受益。
|
||
|
||
---
|
||
|
||
### S2-P6 · 跨端一致性自动验证 | 预算 ~1 天 | 优先级 P0
|
||
|
||
**目标**:能自动回答「H5 / React / Vue2 / Vue3 四个实现是否视觉一致」,并给出差异截图。
|
||
|
||
**依据**:G5。5 端 395 个文件,但**从来没人验证过它们是否真的一致**。契约里写的"各端视觉一致"是纯声称。
|
||
|
||
**依赖**:S1-P3(需要 CI 环境跑 Playwright)。
|
||
|
||
**路径**:
|
||
- `tools/verify-cross-platform.mjs`(新建)
|
||
- `tools/render-harness/`(新建,把 React/Vue 组件渲染成静态 HTML)
|
||
- `tests/cross-platform-report.json`(产出)
|
||
|
||
**步骤**:
|
||
1. **难点**:React/Vue 组件需要构建才能渲染(.jsx/.vue 不能直接在浏览器跑)。
|
||
**零依赖解法**:
|
||
- 方案 A:用 CDN 版 React/Vue(`<script src="unpkg.com/react">`)+ `@babel/standalone` 在浏览器里编译 JSX。缺点:依赖 CDN 可用性。
|
||
- 方案 B:**更推荐** —— 只做**结构性比对**而非像素比对。提取各端的 `className` 集合与 DOM 结构,比对差异。不要求渲染,纯静态分析。
|
||
- 方案 C:混合 —— 结构比对为主,挑选 6 个核心组件做像素比对(核心组件的 CDN 依赖可接受)。
|
||
2. **推荐方案 B + 抽样 C**:
|
||
- 全部 79 组件:静态提取 class 集合与结构骨架,diff 各端
|
||
- 6 个核心组件(button/input/select/table/card/modal):CDN 渲染 + 截图比对
|
||
3. 输出报告:`{ slug, platforms: {h5:[...classes], react:[...], vue2:[...], vue3:[...]}, diffs:[...], severity }`
|
||
|
||
**验收**:
|
||
```bash
|
||
node tools/verify-cross-platform.mjs
|
||
node -e "
|
||
const r=require('./tests/cross-platform-report.json');
|
||
console.log('检查组件:', r.total);
|
||
console.log('完全一致:', r.identical);
|
||
console.log('有差异 :', r.differing);
|
||
console.log('差异样本:', JSON.stringify(r.samples.slice(0,3),null,1));
|
||
"
|
||
```
|
||
|
||
**预期输出**:一份报告,明确列出哪些组件的哪些端存在 class/结构差异。
|
||
|
||
**失败判据**:
|
||
- 脚本报错或无输出
|
||
- 报告里 `total < 79`
|
||
- 差异项没有具体说明(只说"不一致"而不给差异内容)
|
||
|
||
**重要说明**:**这个任务的产出可能揭露一批真实的不一致**。这不是失败 —— 是这项任务的价值。发现的差异应作为新任务包列出,不在本任务内顺手修(避免范围蔓延)。
|
||
|
||
---
|
||
|
||
### S2-P7 · 行为断言 | 预算 ~1.5 天 | 优先级 P1
|
||
|
||
**目标**:测试从"元素存在"升级到"交互后发生什么",覆盖点击/输入/键盘的真实行为。
|
||
|
||
**依据**:G8。当前 12 项/页断言多为结构性(元素存在、有 aria、对比度达标),**没有任何一条验证"点了按钮会怎样"**。
|
||
|
||
**依赖**:无。
|
||
|
||
**路径**:
|
||
- `tests/_runtime.js`(扩展断言引擎)
|
||
- `tests/_behaviors.js`(新建,行为断言库)
|
||
|
||
**步骤**:
|
||
1. 定义行为断言协议(在演示页里声明):
|
||
```html
|
||
<button data-behavior="click-toggles-class:.aa-modal|is-open">打开弹窗</button>
|
||
```
|
||
2. 实现常见行为模式:
|
||
- `click-toggles-class:<selector>|<class>` — 点击切换类
|
||
- `click-sets-attr:<selector>|<attr>|<value>` — 点击设属性
|
||
- `input-updates:<selector>|<text>` — 输入后状态变化
|
||
- `keyboard-activates:<key>` — 键盘触发
|
||
- `focus-trap:<container>` — 弹窗焦点锁定
|
||
3. 在 6 个核心组件(button/modal/select/input/table/tabs)的演示页里标注行为断言作为试点。
|
||
4. 断言结果并入现有报告结构(`matrix:behavior:*`)。
|
||
|
||
**验收**:
|
||
```bash
|
||
# 1) 行为断言库存在且语法正确
|
||
node --check tests/_behaviors.js && echo "syntax OK"
|
||
|
||
# 2) 6 个试点组件有行为断言
|
||
grep -l "data-behavior" frameworks/{Button,Modal,Select,Input,Table,Tabs}.html | wc -l
|
||
# 期望输出 6
|
||
|
||
# 3) 回归里出现行为断言
|
||
# 跑 _collect.html,检查 report.json 的 failureKinds 含 matrix:behavior:*
|
||
```
|
||
浏览器实测:点击弹窗按钮后,`is-open` 类被添加(观察 DOM)。
|
||
|
||
**预期输出**:
|
||
```
|
||
syntax OK
|
||
6
|
||
```
|
||
|
||
**失败判据**:
|
||
- 试点组件少于 6 个
|
||
- 行为断言在回归报告里不出现
|
||
- 断言只是"元素存在"换个名字(无实际交互逻辑)
|
||
|
||
---
|
||
|
||
### S3-P8 · RTL 支持 | 预算 ~2 天 | 优先级 P1
|
||
|
||
**目标**:`<html dir="rtl">` 时布局正确镜像,无错位。
|
||
|
||
**依据**:G7。逻辑属性 **0** 处,物理属性(`margin-left` 等)出现在 **22** 个文件。竞品 7 家里 3 家有 RTL。
|
||
|
||
**依赖**:S2-P5(暗色完成后改样式更安全,减少冲突)。
|
||
|
||
**路径**:
|
||
- `frameworks/*.css`(22 个含物理属性的文件)
|
||
- `frameworks/*.html` 内嵌样式
|
||
- `.design_library/aurora-admin/colors_and_type.css`(如需要在文档说明约定)
|
||
|
||
**步骤**:
|
||
1. **批量迁移物理→逻辑属性**:
|
||
| 物理 | 逻辑 |
|
||
|---|---|
|
||
| `margin-left` | `margin-inline-start` |
|
||
| `margin-right` | `margin-inline-end` |
|
||
| `padding-left/right` | `padding-inline-start/end` |
|
||
| `left` / `right`(定位) | `inset-inline-start/end` |
|
||
| `text-align: left/right` | `text-align: start/end` |
|
||
| `border-left/right` | `border-inline-start/end` |
|
||
2. **注意例外**:图标方向类(箭头、返回)需要 `transform: scaleX(-1)` 而非属性迁移。
|
||
3. **写一个 RTL 演示页**:`site/scenario/user-management-rtl.html`,用于人工验收。
|
||
4. 增加 RTL 断言:`matrix:rtl-safe`,检测是否还有物理属性的残留。
|
||
|
||
**验收**:
|
||
```bash
|
||
# 1) 物理属性清零
|
||
n=$(grep -l "margin-left\|margin-right\|padding-left\|padding-right" frameworks/*.css 2>/dev/null | wc -l)
|
||
echo "剩余物理属性文件: $n"
|
||
test "$n" -eq 0 && echo "RTL migration OK"
|
||
|
||
# 2) 逻辑属性已使用
|
||
grep -l "margin-inline\|padding-inline\|inset-inline" frameworks/*.css | wc -l
|
||
# 期望 ≥ 22
|
||
```
|
||
浏览器实测:`user-management-rtl.html` 加 `dir="rtl"`,确认布局镜像无错位(附截图)。
|
||
|
||
**预期输出**:
|
||
```
|
||
剩余物理属性文件: 0
|
||
RTL migration OK
|
||
22+
|
||
```
|
||
|
||
**失败判据**:
|
||
- 仍有物理属性残留
|
||
- RTL 下出现元素重叠/溢出
|
||
- 图标方向错误(如右箭头在 RTL 下仍指右)
|
||
|
||
---
|
||
|
||
### S3-P9 · FAQ 页 | 预算 ~1 天 | 优先级 P2
|
||
|
||
**目标**:新增 `#/faq` 页,自动聚合 139 条 `unknowns` + 101 条 `doNotInvent`,形成可检索的问答。
|
||
|
||
**依据**:契约里已有 240 条结构化条目,**现成素材没被利用**。Ant Design 每组件 FAQ 是行业惯例。
|
||
|
||
**依赖**:无。
|
||
|
||
**路径**:
|
||
- `site/app.js`(新增 `renderFaq`)
|
||
- `site/index.html`(导航加 FAQ 链接)
|
||
- `site/i18n.js`(文案)
|
||
|
||
**步骤**:
|
||
1. `build-site.ps1` 已把 contract 注入 `data.js`(字段 `unknowns` / `doNot`),直接消费即可。
|
||
2. 渲染两种视图:
|
||
- **按组件**:每个组件列出它的 unknowns("规范未明示")与 doNotInvent("不要自行发明")
|
||
- **按分类**:把相似的 unknowns 聚类(如"最大宽度""省略方式"跨多个组件出现)
|
||
3. 加搜索过滤(复用 `_runtime` 的思路,纯前端)。
|
||
|
||
**验收**:
|
||
```bash
|
||
# 1) 路由可达
|
||
curl -s http://127.0.0.1:3311/site/index.html | grep -q 'href="#/faq"' && echo "nav OK"
|
||
# 2) 数据完整注入
|
||
node -e "
|
||
const d=require('./site/data.json');
|
||
const u=d.components.reduce((s,c)=>s+((c.contract&&c.contract.unknowns)||[]).length,0);
|
||
const dn=d.components.reduce((s,c)=>s+((c.contract&&c.contract.doNot)||[]).length,0);
|
||
console.log('unknowns:',u,'doNotInvent:',dn);
|
||
if(u<139||dn<101){console.error('FAIL: 契约数据缺失');process.exit(1)}
|
||
console.log('data OK');
|
||
"
|
||
```
|
||
浏览器实测:`#/faq` 显示 79 个组件的条目,搜索"宽度"能过滤出相关项。
|
||
|
||
**预期输出**:
|
||
```
|
||
nav OK
|
||
unknowns: 139 doNotInvent: 101
|
||
data OK
|
||
```
|
||
|
||
**失败判据**:条目数少于 139/101,或页面空白。
|
||
|
||
---
|
||
|
||
### S4-P10 · Figma 资源 | 预算 ~2 天 | 优先级 P2
|
||
|
||
**目标**:产出可导入 Figma 的变量集与组件描述,设计师能直接用同一套令牌。
|
||
|
||
**依据**:竞品标配 Figma/Sketch 资源。本项目已有 `site/tokens/figma.json`(Tokens Studio 格式),但**没有 Figma Variables 原生格式**。
|
||
|
||
**依赖**:S1-P2(需稳定的令牌导出管线)。
|
||
|
||
**路径**:
|
||
- `tools/export-figma.mjs`(新建)
|
||
- `dist/figma/`(产出)
|
||
|
||
**步骤**:
|
||
1. 产出 **Figma Variables JSON**(与 Tokens Studio 格式不同,是 Figma 原生 API 格式):
|
||
- 色彩变量 → `{ "color": { "brand": { "type": "COLOR", "value": {...} } } }`
|
||
- 数值变量(间距/圆角/字号)→ `FLOAT`
|
||
- 建立 Light / Dark **两种 mode**(呼应 S2-P5)
|
||
2. 产出组件清单 Markdown(供设计师建组件时参考):每个组件的变体维度 + 尺寸 + 状态。
|
||
3. 写导入说明(`dist/figma/README.md`)。
|
||
|
||
**验收**:
|
||
```bash
|
||
node tools/export-figma.mjs
|
||
node -e "
|
||
const v=require('./dist/figma/variables.json');
|
||
const colors=Object.keys(v.color||{}).length;
|
||
console.log('色彩变量:', colors);
|
||
console.log('模式:', Object.keys(v.modes||{}).join(', '));
|
||
if(!v.modes||!v.modes.Dark){console.error('FAIL: 缺少 Dark 模式');process.exit(1)}
|
||
console.log('figma export OK');
|
||
"
|
||
```
|
||
|
||
**预期输出**:
|
||
```
|
||
色彩变量: 24+
|
||
模式: Light, Dark
|
||
figma export OK
|
||
```
|
||
|
||
**失败判据**:无 Dark 模式、变量数明显少于令牌数、JSON 不符合 Figma Variables 结构。
|
||
|
||
---
|
||
|
||
### S4-P11 · 模板页库 | 预算 ~2 天 | 优先级 P2
|
||
|
||
**目标**:从 1 个场景页扩展到 5 个典型后台页面模板,展示组件组合用法。
|
||
|
||
**依据**:现有 `site/scenario/user-management.html` 是唯一的组合示范。模板页是"能否直接用"的关键 —— 用户要的不是组件,是页面。
|
||
|
||
**依赖**:无。
|
||
|
||
**路径**:`site/scenario/*.html`(新增 4 个)
|
||
|
||
**步骤**:
|
||
1. 选定 4 个典型场景(覆盖不同组件组合):
|
||
- `login.html` — 登录页(输入类组件 + 表单校验)
|
||
- `dashboard.html` — 数据看板(图表 + 指标卡 + 表格)
|
||
- `order-list.html` — 列表管理(表格 + 筛选 + 分页 + 批量操作)
|
||
- `settings.html` — 设置页(Tab + 表单 + 开关组)
|
||
2. 每个模板页只用现有令牌与 `components.css`,纯 HTML + 原生 JS(零依赖)。
|
||
3. 加到首页入口与 sitemap。
|
||
|
||
**验收**:每个模板页在浏览器实测可交互(筛选、分页、提交有反馈),附截图。
|
||
|
||
**失败判据**:页面白屏、交互无效、用了非项目内的样式。
|
||
|
||
---
|
||
|
||
### S4-P12 · 版本发布流程 | 预算 ~1 天 | 优先级 P3
|
||
|
||
**目标**:有明确的 SemVer 发布流程与自动化。
|
||
|
||
**依赖**:S1-P2。
|
||
|
||
**步骤**:
|
||
1. `tools/release.mjs`:从 CHANGELOG 提取版本 → 更新 `package.json` → 打 tag → 提示推送。
|
||
2. 文档化到 `CONTRIBUTING.md`。
|
||
|
||
---
|
||
|
||
## 四 · 显式不做(及理由)
|
||
|
||
> 这份清单同样重要 —— 没有它,执行模型会以为"漏了",或者在错误的时机自作主张。
|
||
|
||
| 不做 | 理由 | 什么条件下应该做 |
|
||
|---|---|---|
|
||
| **不引入打包器**(Vite / Rollup / esbuild) | 破除零依赖约束的代价远大于收益;本项目的卖点就是"打开 HTML 就能用" | 若未来要发布 ESM/CJS 模块化包,先评估是否需要独立仓库 |
|
||
| **不做像素级视觉回归**(全量) | 79 组件 × 5 端 = 395 张基准图,维护成本极高且易误报(抗锯齿/字体渲染差异) | P6 已包含「6 个核心组件抽样像素比对」,够用 |
|
||
| **不做 SSR / SSG** | 文档站是纯静态 SPA,爬虫需求已由 `site/components/*.html` 薄壳 + sitemap 解决 | 若 SEO 成为核心指标,再评估 |
|
||
| **不做多主题商店**(Ant Design 式) | 已有 6 套预设 + 令牌导出,改色能力已足够;主题商店是运营功能非工程功能 | 产品化阶段(S4 之后) |
|
||
| **不重写 `app.js`** | 2064 行单文件虽不理想,但功能正确、回归 100%。重构风险 > 收益 | 若某任务包因它受阻(如 P4 代码拆分),**局部**改造而非重写 |
|
||
| **不改 `frameworks/` 的视觉** | 那是规范原文的忠实实现,改了会破坏契约一致性 | 只有规格原文变更时才同步 |
|
||
| **不做 Storybook 集成** | 与零依赖冲突,且 Playground(v1.2.0)已覆盖在线试玩需求 | 不考虑 |
|
||
| **不做 React/Vue 单元测试**(Jest/Vitest) | 与零依赖冲突;跨端一致性靠 P6 的静态比对 + 抽样渲染 | 若组件逻辑复杂化到静态分析无法覆盖 |
|
||
|
||
---
|
||
|
||
## 五 · 未解问题(需用户或后续规划决策)
|
||
|
||
> 这些问题我作为规划师**无法单方面决定**,列出供决策。
|
||
|
||
| # | 问题 | 影响面 | 我的建议 |
|
||
|---|---|---|---|
|
||
| Q1 | **是否发布到 npm?** 涉及包名占用、发布权、后续维护承诺 | S1-P2 | 建议发。当前无分发渠道是最大阻塞,且 npm 上同名包大概率未被占用 |
|
||
| Q2 | **目标用户是谁?** 内部团队 / 开源社区 / 商业化产品,三者的优先级与验收标准不同 | 全局 | 建议先按「内部团队 + 开源复用」定位(对应 S1-S2 的优先级) |
|
||
| Q3 | **是否有设计团队协作?** 若没有,S4-P10 的 Figma 产出无人使用 | S4-P10 | 建议推迟到有设计资源时再做,或降级为「Figma Variables JSON 导出」只做工程侧 |
|
||
| Q4 | **是否需要 RTL?** 取决于是否有中东/希伯来语市场 | S3-P8 | 若无明确市场,降级为 P2 或推迟。迁移成本高(22 个文件) |
|
||
| Q5 | **性能预算的底线是多少?** 我定的 300KB 是经验值 | S1-P4b | 建议以「3G 网络首屏可交互 < 3s」反推预算 |
|
||
| Q6 | **暗色模式下演示 iframe 是否反色?** 两种都有道理 | S2-P5 | 建议反色(用户开暗色就是要整体变暗),但需人工验收视觉 |
|
||
|
||
---
|
||
|
||
## 六 · 风险登记
|
||
|
||
| 风险 | 影响 | 缓解 |
|
||
|---|---|---|
|
||
| 约束冲突:CI 需要 Playwright,但"零依赖" | 中 | 明确区分**运行时依赖**(保持零)与**构建/测试依赖**(可引入 devDependencies),并在 README 写清 |
|
||
| S2-P6 暴露大量跨端不一致 | 中 | 已在任务包里说明"发现即价值",差异作为新任务列出,不顺手修 |
|
||
| 暗色反色后视觉倒退 | 中 | 强制对比度脚本验证 + 人工截图验收 |
|
||
| RTL 迁移破坏现有布局 | 中 | 迁移后跑八次回归;逐文件比对渲染截图 |
|
||
| `data.js` 拆分影响 For Agents 承诺 | 高 | 明确要求 `data.json` 保持完整,只拆 `data.js` |
|
||
| 用户未确认许可证类型 | 中 | 默认 MIT 并在交付说明标注"如需变更请告知" |
|
||
|
||
---
|
||
|
||
## 七 · 验收总纲
|
||
|
||
任一任务包完成,必须同时满足:
|
||
|
||
1. **给出验收命令的完整输出**(不是"我以为跑过了")
|
||
2. **跑八次回归**:`100% / 0 失败 / 0 超时`
|
||
3. **`CHANGELOG.md` 有对应条目**(`[Unreleased]` 下)
|
||
4. **本文件对应任务包下追加 `✅ 完成于 <commit-hash>`**
|
||
5. **若发现新问题**:写成新任务包追加到本文件,不在原任务里顺手修
|
||
|
||
---
|
||
|
||
## 附 · 执行状态总览
|
||
|
||
> **执行模型看这里**:找下一个可开工的任务。状态为「待开始」且依赖已满足的最优先任务就是你的目标。
|
||
|
||
| ID | 任务 | 阶段 | 优先级 | 预算 | 依赖 | 状态 |
|
||
|---|---|---|---|---|---|---|
|
||
| P1 | LICENSE | S1 | **P0** | 10 min | — | ✅ **已完成**(MIT) |
|
||
| P2 | npm 分发 | S1 | **P0** | 2 h | P1 ✅ | ✅ **已完成**(dist 构建 + npm pack 115.9KB) |
|
||
| P3 | CI 回归 | S1 | **P0** | 1.5 h | — | ✅ **已完成**(workflow + runner 重构 + exit code) |
|
||
| P4 | `data.js` 瘦身 | S1 | **P0** | 3 h | — | ✅ **已完成**(data.js 98KB/sources 395/data.json 完整/回归 1003/1003,见 c65a69c) |
|
||
| P5 | 暗色模式 | S2 | **P0** | 1 d | P4 ✅ | ✅ **已完成**(令牌组31/对比度10项≥4.5/10页实测/DARK VERIFY 32/32/首屏292KB/回归1003/1003,Q6选A) |
|
||
| P6 | 跨端一致性验证 | S2 | **P0** | 1 d | P3 | ⚪ 待 P3 |
|
||
| P7 | 行为断言 | S2 | P1 | 1.5 d | — | 🟢 可开工(优先级低于 P2-P4) |
|
||
| P8 | RTL | S3 | P1 | 2 d | P5 | ⚪ 待 P5 |
|
||
| P9 | FAQ 页 | S3 | P2 | 1 d | — | 🟢 可开工(优先级低) |
|
||
| P10 | Figma 资源 | S4 | P2 | 2 d | P2 | ⚪ 待 P2 |
|
||
| P11 | 模板页库 | S4 | P2 | 2 d | — | 🟢 可开工(优先级低) |
|
||
| P12 | 版本发布流程 | S4 | P3 | 1 d | P2 | ⚪ 待 P2 |
|
||
|
||
### 推荐执行顺序
|
||
|
||
```
|
||
P3(CI,无依赖最快见效)
|
||
→ P4(瘦身,收益最大)
|
||
→ P2(分发,解除交付阻塞)
|
||
→ P5 + P6(可信度双支柱)
|
||
→ P7 → P8 → P9 → P10 → P11 → P12
|
||
```
|
||
|
||
**为什么 P3 排第一**:它是唯一能让后续所有改动**自动受保护**的任务 —— 有了 CI,其他任务的质量不再依赖人工记得跑回归。
|
||
|
||
**为什么 P4 第二**:实测净减 887 KB(991KB → ~110KB),收益/成本比最高,且依赖分析已完成。
|
||
|
||
**并行机会**:P2 与 P4 互不阻塞,可由两个模型同时做。P3 完成后应立即合并,让后续任务都在 CI 保护下。
|
||
|
||
---
|
||
|
||
## 附 · 规划修正记录
|
||
|
||
> 执行中发现规划与实际不符时,**以实测为准**,在此登记。
|
||
|
||
| 日期 | 任务 | 规划原写 | 实测 | 处理 |
|
||
|---|---|---|---|---|
|
||
| 2026-09-11 | P4 | `data.js` 目标 < 400 KB(推测 `sources` 是最大头) | `sources` 实测占 **89.6%**(888KB/991KB);拆出后可达 **~110KB** | 目标改为 < 150 KB,策略与体积数据全部替换为实测 |
|
||
| 2026-09-11 | P4 | 预计算 API 表估算 < 30 KB | 实测 **1.0 KB**(比估算乐观 30 倍) | 更新为实测值 |
|
||
| 2026-09-11 | P2 | 包名可用性未知 | registry 查询:`aurora-admin-design` **未被占用** | 补入「前置验证已完成」 |
|
||
| 2026-09-11 | P4 | 只说「改成 fetch」,未识别难点 | `app.js` 有 **10 处**消费 `sources`,其中 2 处是**渲染期同步解析** | 补入「依赖分析」与三阶段执行建议 |
|
||
| 2026-09-11 | P2/P4 | 验收命令有 3 处会误判(npm 不可用时误报 OK 等) | 实测触发 | 已改写为显式判断 exit code |
|
||
|