一个周三下午,Vercel 构建失败。错误日志指向一个未定义的 Tailwind 工具类。设计师在 Figma 里把一个核心颜色变量从 blue-500 改名成了 brand-blue-primary,设计团队发布了更新,把新 token 推到了仓库,前端团队拉了新的 JSON 文件。没人记得同步改 Tailwind 配置文件。

打开网易新闻 查看精彩图片

构建崩了,因为有个组件还在用 bg-blue-500。这个 token 在设计系统里已经不存在了。只要设计 token 和框架配置是两套东西,中间就永远留着一道手工维护的缝。

大多数团队的做法是把 Figma 变量导出成 JSON,丢进 tokens 文件夹,然后由开发手动把 JSON 里的值映射到 Tailwind 的 theme 对象。三个颜色时这招没问题,几百个变量、多套主题时就彻底散架。设计 token 的嵌套结构很少刚好对上 Tailwind 的预期,嵌套太深还会丢掉自动补全。

Figma 变量可以按 W3C Design Token 格式导出,每个 token 带 value 和 type。思路是写一个 Node 脚本,递归读取这棵嵌套对象,拍平成 Tailwind 认识的扁平字典——colors.brand.blue.500 变成 brand-blue-500,正好对上 Tailwind 的类名命名习惯。

拿到扁平对象后,直接生成一个 TypeScript 配置文件,而不是 JSON。这样标准插件和类型定义都能保留,只把动态颜色注入 theme 的 extend 里。脚本一跑,整个 Tailwind 配置被最新 token 覆盖,不再需要任何手工映射。设计师在 Figma 里改了名,脚本生成的配置里就是新名字。

本地跑脚本比手工映射强,但还不算全自动——开发拉完新 token 可能忘了跑。真正合适的位置是持续集成流水线。用 GitHub Actions 监听:只要 PR 改动了 tokens 目录下的 JSON 文件,工作流就触发,跑解析脚本,把更新后的 Tailwind 配置提交回同一个 PR。

  • 触发条件:pull_request 且路径命中 tokens 下的 JSON
  • 生成:跑 generate-tailwind 脚本重写配置
  • 回写:以 github-actions[bot] 身份提交并 push

这套流程把人从同步环节里彻底摘出去。设计 token 是唯一事实来源,框架配置只是对源变化的反应。

原来的 Vercel 构建失败被彻底解决。设计师在 Figma 改名后,PR 里带着更新过的 JSON,Action 自动更新 tailwind.config.ts。代码评审时,开发能直接看到 Tailwind 类会怎么变。设计决策的 diff 就摆在框架配置旁边,设计和工程被迫保持对齐。

代码侧靠解析脚本加 CI 流水线就够了,但还得有可靠的办法把 token 从 Figma 送进那个 PR。作者为此做了一个叫 Design System Sync 的 Figma 插件,把设计 token 和变量直接导出到 GitHub 或 Bitbucket,自动生成带清晰 diff 的 PR 并指派评审人,原生导出 W3C Design Tokens 格式,可以直接喂给上面那条 GitHub Action。

把 Figma 直接接到 Tailwind 配置上,省下的是大量找缺失工具类的调试时间。不用再追着找哪个类没了,可以重新信任自己的设计系统。