企业级设计系统的 Token 治理:权限、审批与变更追溯
2026/7/22 0:18:11 网站建设 项目流程

企业级设计系统的 Token 治理:权限、审批与变更追溯

一、引言:设计系统不是一张色彩表,而是一面照出团队协作真相的镜子

在设计系统的世界里,有一个残酷的真相:99% 的设计系统最终都会走向"Token 腐败"。那些被精心定义的颜色值、间距值、字体大小,会在产品迭代的漫长岁月里,被一小撮"紧急需求"逐一击穿——"这个页面太紧急了,先用硬编码的颜色吧,后面再改"、"产品说这个按钮必须再大 2px,来不及走 Token 变更流程了"。

我在上一家公司接手设计系统的维护工作时,打开 Figma Token 面板看到的景象让我倒吸一口凉气:一套本应只有 56 个颜色 Token 的设计系统,蔓延出了 247 个"变体"。blue-6blue-6-dark的区别只是前者透明度是 0.95 而后者是 0.92。团队里 12 个前端工程师,每个人都"顺手"往设计系统里塞了几个自己需要的 Token,而且没有任何人记得为什么需要这些 Token。

这不是个别现象。在不引入治理机制的设计系统中,Token 数量的增长速度与开发人员数量的平方成正比——我称之为"Token 膨胀定律"。每个新加入的工程师都会发现"已有的 Token 满足不了我的需求",然后创造出新的变体,而这些变体又成为下一个工程师感到不满意的起点。

Token 治理不是要限制创造力,而是要保护"共识"。设计系统的本质是团队对"什么是好的设计"达成的共识,而 Token 是这个共识的物化载体。当 Token 失去治理,共识就开始瓦解;当共识瓦解,设计系统就只剩下一个漂亮的 Figma 文件和一堆"仅供参考"的变量名。

本篇文章聚焦 Token 治理的三个核心支柱:权限控制、审批流程和变更追溯。这不是一篇关于"如何定义 Token"的文章,而是一篇关于"如何保护 Token 不被腐化"的文章。在一个 50 人以上的前端团队中,这三者的缺失几乎必然导致设计系统的崩塌。

二、底层机制与原理深度剖析

Token 治理的本质是一个"变更管理"问题。每一次 Token 的增删改,都是一次对设计共识的修改。当修改是随意的、无记录的、不可追溯的,设计系统就会从"单一事实源"蜕变为"混乱的意见集合"。

权限模型设计

Token 治理的权限模型不能是简单的"管理员-普通用户"二分类。在一个成熟的设计系统中,权限应该是基于角色的、可配置的多层级模型:

  • Consumer(消费者):只能读取和使用已发布的 Token,不能做任何修改。这是最大范围的权限组,覆盖全团队所有前端和设计师。
  • Contributor(贡献者):可以提交 Token 变更提案,但不能直接修改正式 Token。提案需要经过维护者的审批才能生效。
  • Maintainer(维护者):可以审批和合并 Token 变更,负责维护设计系统的一致性。通常由资深设计师或前端架构师担任。
  • Owner(管理员):拥有最高权限,可以修改权限配置、处理紧急情况。这一角色应严格控制在 1-2 人。

审批流程的设计哲学

Token 审批流程的核心挑战在于:既要防止"腐败",又不能成为"阻塞"。如果每次 Token 变更都需要三天才能通过审批,最终的结果是开发团队绕过流程——直接硬编码。

我推荐的方案是"分级审批":

  • 补丁级变更(Patch):Token 值微调(如颜色亮度±3%以内),自动通过,事后追溯。
  • 次要变更(Minor):新增一个语义 Token(如新增一个警示性色彩),需要 1 个 Maintainer 审批。
  • 重大变更(Major):修改已有全局 Token、删除 Token、重构 Token 层级结构,需要 2 个 Maintainer 审批 + 影响面分析通过。

三、生产级代码实现

/** * Token 治理系统的核心数据模型 * * 设计哲学: * - 每个 Token 都有独立版本号,支持渐进式升级 * - 变更提案不可修改(追加而非覆盖),保证审计完整性 * - 语义化命名不依赖视觉值,方便深色模式等主题切换 */ /** Token 的基本单元 */ interface DesignToken { /** 唯一命名,如 "color.primary.500" */ name: string; /** Token 分组,如 "color", "spacing", "typography" */ group: string; /** 当前生效的值 */ value: string; /** 值的类型,决定 UI 编辑器的渲染方式 */ type: 'color' | 'dimension' | 'number' | 'string' | 'gradient' | 'shadow'; /** 语义说明,帮助贡献者理解 Token 的用途 */ description: string; /** 当前版本号 */ version: number; /** 状态 */ status: 'active' | 'deprecated' | 'draft'; /** 废弃时指向的替代 Token */ replacedBy?: string; } /** Token 变更提案 */ interface TokenChangeProposal { /** 提案唯一 ID */ id: string; /** 提案标题,需简明描述变更意图 */ title: string; /** 变更类型 */ type: 'create' | 'update' | 'deprecate' | 'delete'; /** 目标 Token 名称 */ targetToken: string; /** 变更前的值(update/deprecate/delete 时必填) */ oldValue?: string; /** 变更后的值(create/update 时必填) */ newValue: string; /** 变更原因说明 */ reason: string; /** 关联需求单或设计稿链接 */ reference?: string; /** 提案人 */ proposer: string; /** 当前的审批状态 */ approvalStatus: 'pending' | 'approved' | 'rejected'; /** 审批意见列表 */ approvals: ApprovalRecord[]; /** 创建时间 */ createdAt: Date; } /** 审批记录 */ interface ApprovalRecord { /** 审批人 */ reviewer: string; /** 审批意见 */ comment: string; /** 审批结果 */ decision: 'approve' | 'reject'; /** 审批时间 */ timestamp: Date; } /** * Token 治理引擎 * 负责权限验证、合规检查和变更追溯 */ class TokenGovernanceEngine { /** Token 存储 */ private tokens: Map<string, DesignToken> = new Map(); /** 变更历史(不可变日志) */ private changeLog: TokenChangeProposal[] = []; /** 用户角色映射 */ private roles: Map<string, string> = new Map(); /** * 提交 Token 变更提案 * * @param proposal 变更提案 * @param user 当前操作用户 * @throws 用户没有提案权限时抛出错误 */ submitProposal(proposal: TokenChangeProposal, user: string): void { // 权限验证 const role = this.roles.get(user); if (!role || role === 'consumer') { throw new Error(`用户 ${user} 无 Token 变更权限,当前角色: ${role || '未分配'}`); } // 自动合规检查 const violations = this.validateProposal(proposal); if (violations.length > 0) { // 合规检查不通过,自动驳回 proposal.approvalStatus = 'rejected'; proposal.approvals.push({ reviewer: 'system', comment: `自动合规检查未通过: ${violations.join('; ')}`, decision: 'reject', timestamp: new Date() }); this.changeLog.push(proposal); throw new Error(`Token 变更合规检查失败: ${violations.join('; ')}`); } // 记录提案 this.changeLog.push(proposal); } /** * Token 合规验证 * * 检查项包括: * 1. 命名规范:必须符合 "group.category.variant" 格式 * 2. 值合法性:颜色值必须是有效的 hex/rgba * 3. 唯一性:同组内 Token 名称不能重复 * 4. 废弃保护:正在被其他 Token 引用的 Token 不可删除 */ private validateProposal(proposal: TokenChangeProposal): string[] { const violations: string[] = []; // 命名格式检查 const namingPattern = /^[a-z]+(\.[a-z]+)+$/; if (!namingPattern.test(proposal.targetToken)) { violations.push( `Token 命名 "${proposal.targetToken}" 不符合规范,应为 "group.category.variant" 格式` ); } // 颜色值合法性检查 if (proposal.targetToken.includes('color')) { const colorPattern = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/; if (proposal.newValue && !colorPattern.test(proposal.newValue)) { violations.push( `颜色 Token 值 "${proposal.newValue}" 不符合 hex 格式,应为 #RRGGBB 或 #RRGGBBAA` ); } } // 同组名称唯一性检查 if (proposal.type === 'create') { const existingNames = Array.from(this.tokens.keys()); if (existingNames.includes(proposal.targetToken)) { violations.push(`Token "${proposal.targetToken}" 已存在,不能重复创建`); } } // 废弃保护检查 if (proposal.type === 'delete') { const dependents = Array.from(this.tokens.values()) .filter(t => t.replacedBy === proposal.targetToken); if (dependents.length > 0) { violations.push( `Token "${proposal.targetToken}" 被 ${dependents.length} 个 Token 引用,不可删除` ); } } return violations; } /** * 影响面分析 * 扫描代码库中使用了被修改 Token 的所有文件 * * 生产环境中应接入 AST 解析工具, * 这里用简化的字符串匹配做演示 */ analyzeImpact(tokenName: string, files: string[]): ImpactReport { const affectedFiles: string[] = []; const tokenVar = `var(--${tokenName})`; for (const file of files) { // 实际项目中应使用正则匹配 CSS 变量引用 if (file.includes(tokenVar)) { affectedFiles.push(file); } } return { token: tokenName, affectedFiles, totalAffected: affectedFiles.length, // 根据影响范围决定审批级别 requiredApprovalLevel: affectedFiles.length > 10 ? 'major' : 'minor' }; } } /** 影响面分析报告 */ interface ImpactReport { token: string; affectedFiles: string[]; totalAffected: number; requiredApprovalLevel: 'minor' | 'major'; }

四、边界分析与架构权衡

关键缺点:

  1. 流程成本过高。审批流程最直接的代价是延迟。在一个两周发版节奏的团队中,Token 变更可能需要等待一周才能通过审批,这会倒逼开发者绕过流程(硬编码),反而加剧问题。

  2. 小型团队不适用。当团队人数低于 5 人时,Token 治理的收益远低于其成本。5 人以下的团队,口头沟通和 Code Review 足够覆盖 Token 的一致性需求。

  3. 工具链依赖重。一个完善的 Token 治理系统需要 Figma 插件(设计师端)、CLI 工具(开发者端)、CI/CD 集成(自动化检查)和文档站点(查找和预览),这些工具链的搭建和维护成本不容小觑。

  4. Token 粒度困境。过于细致的 Token 治理会让"创建新 Token"变得过于困难,导致设计师和开发者倾向于复用不恰当的 Token(比如把"成功色"用在"通过"标签上),产生语义错误。

适用边界:

适用团队不适用团队
10 人以上前端团队5 人以下小型团队
多产品线的平台型产品单一产品快速迭代期
有专职设计系统维护者全栈开发、设计师兼任前端
对外交付的标准化产品内部工具、一次性项目

五、总结

设计系统的 Token 治理,不是技术问题,而是组织问题。技术可以帮你实现权限控制、自动化检查和变更追溯,但真正的挑战在于:让团队中的每一个人都认同"遵守规范比方便自己更重要"。

我的实践建议是:治理粒度从粗到细。不要一开始就设计一个完美的、细粒度的 Token 治理流程。从"颜色 Token 不能硬编码"这一条规则开始,当团队形成习惯后,再逐步扩展到间距、字体、阴影等领域。治理流程的效率也很重要——如果一个 Token 变更需要 3 天才能审批通过,你就不是在治理,而是在制造障碍。

最后,也是最重要的一点:Token 治理的目的不是建立一个封闭的围墙,而是构建一个安全的容器。容器让创造变得安全,围墙让创造变得不可能。选择做容器,不要做围墙。


作者:李慕杰(Leo / 8limujie)
一个在设计系统的 Token 丛林里为秩序而战的前端匠人

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询