生成式 AI 正在改变 UI 复用的成本结构。过去,团队通过维护统一的组件包来避免重复开发;现在,只要设计系统足够清晰,模型就能按需生成大量标准界面。真正值得长期集中维护的资产,可能不再是每一个组件实现,而是设计令牌、交互规则、使用指南和自动化测试。
共享组件库的隐性成本正在变得更明显
一个中央组件包看起来能带来复用,但它也会持续产生维护费用:
- 组件 API 需要兼容旧版本;
- 每次调整都要发布、升级并处理依赖冲突;
- 为了覆盖所有业务,组件往往积累大量布尔参数和条件分支;
- 团队需要讨论哪些需求应该进入公共组件,哪些只能留在业务代码中;
- 一个小的视觉改动,可能要等待组件库发版后才能落地。
当模型可以根据明确约束生成按钮、表单、卡片和布局时,复制实现代码的成本迅速下降。此时,继续把所有标准 UI 都包装成长期兼容的公共 API,未必是最经济的选择。
这并不意味着共享组件库应该被全部删除。日期选择器、数据表格、复杂弹窗、富文本编辑器以及经过严格无障碍验证的控件,仍然包含大量不适合反复生成的行为逻辑。变化主要发生在另一端:简单、样式驱动、容易验证的组件,可以从“必须复用的包”转变为“可以重新生成的本地代码”。
应该集中维护的是约束,而不只是实现
如果组件可以重新生成,设计系统就必须从展示文档升级为机器和开发者都能执行的契约。至少应集中管理四类内容:
- 设计令牌:颜色、间距、字体、圆角、阴影和动画时长。
- 语义与交互规则:何时使用主按钮、错误信息放在哪里、加载状态如何表达。
- 无障碍要求:键盘操作、焦点样式、语义标签和 ARIA 使用边界。
- 自动化验证:视觉回归、交互测试、令牌检查和无障碍扫描。
组件实现可以分散在业务仓库中,但这些约束必须保持中央化。否则,生成只会把手工复制粘贴造成的漂移,升级成速度更快的自动化漂移。
一种可行的资产分层方式是:
| 层级 | 是否中央维护 | 例子 |
|---|---|---|
| 设计令牌 | 是 | 颜色、间距、圆角、排版 |
| UI 规则与生成提示 | 是 | 状态要求、无障碍规则、禁用模式 |
| 高复杂度基础控件 | 通常是 | Combobox、DatePicker、DataGrid |
| 标准展示组件 | 可按需生成 | Card、Badge、简单 Button |
| 业务组合组件 | 留在业务侧 | CheckoutSummary、UserQuotaPanel |
一个可执行的“生成后验证”示例
下面假设项目使用 React、普通 CSS 和 Node.js 18 或更高版本。示例并不依赖特定 AI API:可以让模型生成组件,但生成结果必须通过同一套设计契约检查。
先定义中央令牌文件 design-system/tokens.css:
:root {
--color-action-bg: #2457d6;
--color-action-bg-hover: #1946b3;
--color-action-text: #ffffff;
--color-focus-ring: #80a7ff;
--space-2: 0.5rem;
--space-3: 0.75rem;
--radius-md: 0.5rem;
}
生成的业务侧组件 src/Button.jsx 可以保持简单,并直接进入应用源码:
import './Button.css';
export function Button({ children, loading = false, disabled = false, ...props }) {
return (
<button
className='button'
disabled={disabled || loading}
aria-busy={loading}
{...props}
>
{loading ? 'Saving…' : children}
</button>
);
}
对应的 src/Button.css 只能使用批准的设计令牌:
.button {
border: 0;
border-radius: var(--radius-md);
padding: var(--space-2) var(--space-3);
color: var(--color-action-text);
background: var(--color-action-bg);
cursor: pointer;
}
.button:hover:not(:disabled) {
background: var(--color-action-bg-hover);
}
.button:focus-visible {
outline: 3px solid var(--color-focus-ring);
outline-offset: 2px;
}
.button:disabled {
cursor: not-allowed;
opacity: 0.55;
}
接着添加 scripts/check-ui-contract.mjs,检查组件是否引用了不存在的令牌,以及是否绕过令牌直接写入颜色值:
import { readFile } from 'node:fs/promises';
const tokenFile = 'design-system/tokens.css';
const componentFiles = ['src/Button.css'];
const tokens = await readFile(tokenFile, 'utf8');
const defined = new Set(
[...tokens.matchAll(/(--[\w-]+)\s*:/g)].map((match) => match[1])
);
let failed = false;
for (const file of componentFiles) {
const css = await readFile(file, 'utf8');
const used = [...css.matchAll(/var\((--[\w-]+)/g)].map((match) => match[1]);
const unknown = [...new Set(used.filter((name) => !defined.has(name)))];
const rawColorMarkers = ['#', 'rgb(', 'rgba(', 'hsl(', 'hsla('];
const containsRawColor = rawColorMarkers.some((marker) => css.includes(marker));
if (unknown.length > 0) {
console.error(`${file}: unknown tokens: ${unknown.join(', ')}`);
failed = true;
}
if (containsRawColor) {
console.error(`${file}: raw color found; use a design token instead`);
failed = true;
}
}
if (failed) {
process.exitCode = 1;
} else {
console.log('UI contract check passed');
}
在项目根目录运行:
node scripts/check-ui-contract.mjs
真实项目可以把 componentFiles 改为递归扫描,也可以继续加入间距、字体、动画和废弃令牌检查。这个脚本不是完整的设计系统验证器,但它展示了关键变化:团队不再要求所有页面导入同一个 Button 包,而是要求所有 Button 实现遵守同一份可执行契约。
生成组件时,也可以固定使用一段仓库内提示词:
Generate a local React component under src/components.
Source of truth:
- Use only CSS variables defined in design-system/tokens.css.
- Do not add runtime dependencies.
- Prefer semantic HTML over ARIA replacements.
- Include default, hover, focus-visible, disabled, and loading states.
- Keep business-specific props out of generic UI components.
- Add interaction tests for keyboard and disabled behavior.
Return the component, stylesheet, and tests as separate files.
提示词本身也应该像代码一样接受评审和版本管理。模型可以变化,但输入约束和验收门槛不能随意漂移。
不要把“可再生”误解成“无需治理”
按需生成会引入新的风险。不同模型或不同提示词可能产生结构不同但视觉相似的代码;同一个缺陷也可能被复制到多个业务仓库。生成速度越快,代码审查和自动化测试的重要性越高。
可以按以下标准决定是否保留中央组件:
- 行为复杂度高:涉及焦点管理、浮层定位、异步状态或大量键盘交互时,优先共享成熟实现。
- 错误代价高:支付、身份验证、隐私授权等场景不应依赖未经验证的即时生成。
- 变化频率低但复用率高:稳定基础控件继续共享通常更便宜。
- 样式简单且业务差异大:更适合基于令牌在业务侧生成。
- 无法自动验证:在建立测试和检查规则之前,不要急于拆掉现有组件库。
迁移时先改变默认路径
团队不必一次性废弃现有组件包。更稳妥的做法是保留复杂基础控件,同时选择 Badge、Card、空状态和简单表单布局进行试点。
迁移检查清单可以很短:
- 设计令牌是否有稳定名称和明确语义;
- 使用指南能否被转换为具体生成约束;
- CI 是否能发现视觉、交互和无障碍回归;
- 生成代码是否直接归业务团队维护;
- 高频重复模式是否会被重新提升为共享组件;
- 模型升级后是否有固定样例用于回归评估。
生成式 AI 并没有消除复用,而是把复用的中心从“同一份组件代码”移向“同一套设计决策和质量门槛”。组件可以被重新生成,设计系统、规则和测试则必须比过去更可靠。