Files
dudu/doc/frontend-overview.html
T
wangjia 1a8089a96d
ci / server (push) Failing after 10s
ci / design-system (push) Failing after 11s
docs(design): 前端全景文档 + SKILL 闸章节 + 文档索引登记
- doc/frontend-overview.html:一次 UI 改动的标准路径 / 真相源结构 /
  五端消费对照 / 各道闸全景 / L1-L2-L3 分治 / 已知滞后(jiu
  frontend-overview 思想的 dudu 版)
- design/SKILL.md 增补「单源与闸」章节(agent 改 UI 前必读)
- doc/index.html 登记全景文档

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 00:11:50 +08:00

169 lines
11 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>dudu 前端全景:设计真相源与防漂移体系</title>
<style>
:root {
--accent: #4F6EF7;
--accent-text: #3D58DB;
--accent-soft: #EEF1FE;
--bg: #F6F7FA;
--card: #FFFFFF;
--text-1: #1B1E26;
--text-2: #5A6072;
--text-3: #A6ABB8;
--border-1: #E4E6EB;
--positive: #16A34A;
--warning: #E8890C;
--danger: #DC2626;
--code-bg: #1B1E26;
--code-text: #D6DCEA;
}
* { box-sizing: border-box; }
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", "Segoe UI", sans-serif;
background: var(--bg); color: var(--text-1); line-height: 1.75;
}
.container { max-width: 980px; margin: 0 auto; padding: 0 24px 80px; }
header.hero { background: var(--accent); color: #fff; padding: 48px 24px 40px; text-align: center; }
header.hero h1 { margin: 0 0 6px; font-size: 30px; }
header.hero p { margin: 0; opacity: .85; font-size: 15px; }
.chips { margin-top: 16px; }
.chip { display: inline-block; padding: 3px 14px; margin: 3px; background: rgba(255,255,255,.16); border-radius: 999px; font-size: 13px; }
section.card {
background: var(--card); border: 1px solid var(--border-1); border-radius: 14px;
padding: 28px 32px; margin-top: 24px; box-shadow: 0 1px 3px rgba(17,19,26,.05);
}
h2 { font-size: 21px; margin: 0 0 14px; padding-bottom: 8px; border-bottom: 2px solid var(--accent); display: inline-block; }
h3 { font-size: 16px; margin: 22px 0 8px; color: var(--accent-text); }
table { width: 100%; border-collapse: collapse; margin: 10px 0; font-size: 13.5px; }
th, td { border: 1px solid var(--border-1); padding: 7px 11px; text-align: left; vertical-align: top; }
th { background: #F0F1F4; font-weight: 600; }
tr:nth-child(even) td { background: #FCFCFD; }
pre.code, pre.diagram {
background: var(--code-bg); color: var(--code-text); padding: 16px 18px; border-radius: 10px;
overflow-x: auto; font-family: "SF Mono", Menlo, Consolas, monospace; font-size: 12.5px; line-height: 1.55;
}
code.inline { background: var(--accent-soft); color: var(--accent-text); padding: 1px 6px; border-radius: 4px; font-family: "SF Mono", Menlo, monospace; font-size: 12.5px; }
.callout { border-left: 4px solid var(--accent); background: var(--accent-soft); padding: 11px 16px; border-radius: 0 8px 8px 0; margin: 12px 0; font-size: 13.5px; }
.callout.warn { border-color: var(--warning); background: #FCEFD7; }
.tag { display: inline-block; font-size: 12px; padding: 1px 10px; border-radius: 999px; margin-right: 6px; font-weight: 600; }
.tag.green { background: #DCFCE7; color: var(--positive); }
.tag.orange { background: #FCEFD7; color: var(--warning); }
.tag.blue { background: var(--accent-soft); color: var(--accent-text); }
ul, ol { padding-left: 22px; }
li { margin: 3px 0; }
footer { text-align: center; color: var(--text-3); font-size: 13px; margin-top: 44px; }
</style>
</head>
<body>
<header class="hero">
<h1>dudu 前端全景</h1>
<p>设计真相源(design/)· 五端消费 · 防漂移闸体系 —— 参考 jiu ds-flow 思想的非 Flutter 落地</p>
<div class="chips">
<span class="chip">2026-07-11</span>
<span class="chip">登记簿:design/index.html</span>
<span class="chip">闸:design-pipeline/check-ds · check-code · export-tokens --check</span>
</div>
</header>
<div class="container">
<section class="card">
<h2>一、一次 UI 改动的标准路径</h2>
<pre class="diagram">改颜色/字号/间距 design/tokens/*.css 登记
node design-pipeline/export-tokens.mjs
│(直写四端消费位置)
┌──────────┬──────┴──────┬──────────────┐
▼ ▼ ▼ ▼
desktop iOS Swift Android Kotlin 官网 web/
CSS 变量 DuduTheme DuduTheme tokens.css
(直引源) (生成) (生成) (生成,含字体内嵌)
改组件 / 图标 先在 design/ 登记(components/ + index.html 卡;
icons.js + icon-map.json)→ 再到各端实现
提交 pre-commit 自动跑对应闸;CI 三道闸复验</pre>
<div class="callout"><b>核心原则(ds-flow):</b>设计决策只有一个出生地(design/),代码永远是镜像;绕过单源的行为由闸在提交/CI 时拦截。<b>规则写了没上闸 = 没有规则。</b></div>
</section>
<section class="card">
<h2>二、真相源结构(design/</h2>
<table>
<tr><th>路径</th><th>角色</th></tr>
<tr><td><code class="inline">index.html</code></td><td><b>登记簿</b>(活文档主页):token 色板 / 组件卡 / 图标映射 / guidelines / ui_kits 单一入口。新元素必须在此登记(check-ds ④ 强制)。评审:<code class="inline">node design/serve.mjs</code></td></tr>
<tr><td><code class="inline">tokens/*.css</code></td><td>令牌单源:colors(含 --brand-wechat / --overlay-wave/ typography / spacing / effects / fontsOutfit 自托管,禁 CDN</td></tr>
<tr><td><code class="inline">icons.js + icon-map.json</code></td><td>图标单源(Lucide 线条 24 网格)+ 语义名→三端实现映射表;业务代码禁内联 &lt;path&gt;</td></tr>
<tr><td><code class="inline">components/</code>core/forms/voice</td><td>参考组件(React),桌面端直接运行时消费;Icon.jsx 渲染 icons.js</td></tr>
<tr><td><code class="inline">ui_kits/</code>desktop/mobile</td><td>屏级交互原型(新屏 design-first 的出生地)</td></tr>
<tr><td><code class="inline">guidelines/*.card.html</code></td><td>规范卡(品牌/色板/字体/间距/动效)</td></tr>
<tr><td><code class="inline">readme.md / SKILL.md</code></td><td>设计基调、文案基调、视觉硬规则;agent 使用入口</td></tr>
<tr><td><code class="inline">_ds_manifest.json</code></td><td>Claude 设计导出的机读清单——<b>非权威、可能滞后</b>,真相以 tokens/ 与登记簿为准</td></tr>
</table>
</section>
<section class="card">
<h2>三、五端消费方式对照</h2>
<table>
<tr><th></th><th>技术栈</th><th>令牌</th><th>组件/图标</th></tr>
<tr><td>桌面 Mac/Win</td><td>Tauri 2 + React</td><td>vite alias <code class="inline">@dudu/design</code> 直引 tokens CSS(无生成层)</td><td>直接 import design/componentsIcon 组件渲染 icons.js</td></tr>
<tr><td>iOS</td><td>SwiftUI</td><td><code class="inline">ios/dudu/Shared/DuduTheme.swift</code>codegen 直写)</td><td>SF Symbols,须 ∈ icon-map ios 列(check-code 同集闸)</td></tr>
<tr><td>Android</td><td>Compose</td><td><code class="inline">DuduTheme.kt</code>codegen 直写)→ <code class="inline">DuduPalette</code> CompositionLocal</td><td>暂无图标使用;启用后同集闸生效</td></tr>
<tr><td>官网</td><td>静态单页</td><td><code class="inline">web/tokens.css</code>codegencustom props + Outfit data URI</td><td>页面只允许 var(--*);深色板块挂 <code class="inline">data-theme="dark"</code> 复用 dark 令牌</td></tr>
<tr><td>原型自身</td><td>React(浏览器内 Babel</td><td>styles.css @import tokens</td><td>与桌面同一套组件源码</td></tr>
</table>
<div class="callout"><b>codegen 直写消费位置</b>2026-07-11 改):此前生成到 design-pipeline/generated/ 再手工拷贝进 app<code class="inline">--check</code> 守不到真实文件、拷贝已漂移。现直写 + CI 校验真实消费文件,漂移类型整个消除。</div>
</section>
<section class="card">
<h2>四、各道闸全景</h2>
<table>
<tr><th></th><th>拦什么</th><th>何时跑</th></tr>
<tr><td><code class="inline">check-ds.mjs</code><br>真相源自检(7 道)</td><td>① dark 孤儿 token ② var() 断链/@import 缺失 ③ design/ 内裸色 ∉ tokens 值集 ④ 组件未登记登记簿 ⑤ icons.js 重复 key/填充色 ⑥ icon-map ↔ icons.js 双向不同集 ⑦ 界面文案 emoji</td><td>pre-commit(动 design/+ CI</td></tr>
<tr><td><code class="inline">export-tokens.mjs --check</code></td><td>四端令牌产物与源不一致(改了 tokens 忘 regen / 手改生成文件)</td><td>pre-commit(动 design/+ CI</td></tr>
<tr><td><code class="inline">check-code.mjs</code><br>代码侧单源(四端)</td><td>desktop 字面色/内联 &lt;path&gt;iOS 字面色/未登记 SF SymbolAndroid Color(0xweb 字面色</td><td>pre-commit(动端代码)+ CI</td></tr>
</table>
<h3>豁免机制</h3>
<ul>
<li>行级 <code class="inline">ds-ignore: 理由</code> 注释——必须写理由(mac 红绿灯窗饰、手机外壳装饰、alpha 派生色等)</li>
<li>codegen 产物(DuduTheme.*、web/tokens.css)自动豁免</li>
</ul>
<h3>启用</h3>
<pre class="code"># 一次性(每个 clone
git config core.hooksPath .githooks
# 手动全量
node design-pipeline/check-ds.mjs && node design-pipeline/export-tokens.mjs --check && node design-pipeline/check-code.mjs</pre>
</section>
<section class="card">
<h2>五、三层分治规则(L1 / L2 / L3)</h2>
<table>
<tr><th></th><th>规则</th></tr>
<tr><td><b>L1 设计系统元素</b><br>颜色/字号/间距/组件/图标</td><td>先登记 design/tokens / components+登记簿 / icons+map)再写端代码,<b>无例外</b>。闸强制。</td></tr>
<tr><td><b>L2 屏级</b></td><td>屏以 ui_kits 原型为基准;小迭代直改代码但不得引入 L1 违规(闸兜底);整屏改版原型先行。</td></tr>
<tr><td><b>L3 新屏</b></td><td>design-firstui_kits 加屏(serve.mjs 起服务给 URL 评审,不截图)→ 各端实现 → 登记。</td></tr>
</table>
</section>
<section class="card">
<h2>六、已知滞后与后续项</h2>
<ul>
<li><span class="tag orange">todo #26</span>桌面 fidelity 像素闸(Playwright 截 ui_kits 原型 vs Tauri 页面 pixelmatch)——静态闸先行,像素级验收后续补</li>
<li><span class="tag orange">待治理</span>ui_kits 预览页经 unpkg CDN 加载 React/Babel,离线/无代理网络不可用(评审时需网络;可选改为 vendor 本地化)</li>
<li><span class="tag blue">说明</span>_ds_manifest.json 为 Claude 设计导出产物,未纳入闸;以 tokens/ 与登记簿为权威</li>
<li><span class="tag blue">说明</span>移动端不做跨渲染器像素比对(字体度量漂移大,jiu 教训);iOS/Android 一致性由 token codegen + 同集闸保障</li>
</ul>
</section>
<footer>dudu · 前端全景 · 2026-07-11 · 变更走 feat/design-truth-source</footer>
</div>
</body>
</html>