Figma Console MCP Token格式化引擎源码解读:10种输出格式如何实现
【免费下载链接】figma-console-mcpYour design system as an API. Connect AI to Figma for extraction, creation, and debugging.项目地址: https://gitcode.com/gh_mirrors/fi/figma-console-mcp
Figma Console MCP(figma-console-mcp)是一个开源的 Figma 设计系统 MCP 服务,核心理念是 "Your design system as an API"——它通过 AI 连接 Figma,完成设计 Token 的提取、创建与调试。其中最硬核的模块,是能把 Figma 变量一键转换为 CSS 变量、Tailwind v3/v4 配置、SCSS 变量、TS 模块、DTCG 标准 JSON 等10 种以上输出格式的 Token 格式化引擎。本文将从源码视角拆解它的实现原理 🎨
整体架构:一个"规范化中间态" + 格式化器分发
整个引擎位于 src/core/tokens/ 目录下,采用经典的Canonical Document(规范化文档)+ 分发器(Dispatcher)架构:
Figma 变量 → figma-converter → TokenDocument(中间态) ↓ format() 分发器 ↓ ↓ ↓ ↓ DTCG CSS Tailwind SCSS ...关键洞察:所有格式器都不直接读 Figma 数据,而是消费统一的TokenDocument结构(定义在 types.ts)。这意味着:
- ✅ 新增一种输出格式 = 新增一个纯函数,互不干扰
- ✅ 每种格式器的输入输出契约一致:
(doc, options) → FormatResult - ✅ 解析(parsers)与格式化(formatters)对称设计,支持双向同步
分发逻辑集中在 formatters/index.ts 的format()函数,一个 switch 分支把请求路由到具体格式器,并用 TypeScript 的never穷尽检查保证新格式不会被漏掉。
12 种导出格式在 types.ts 中以ExportFormat联合类型声明,按优先级分为四类:规范输出(DTCG、Tokens Studio)、即开即用的 CSS 家族(CSS 变量、Tailwind v4/v3、SCSS、Less)、代码模块(TS 模块、JSON 平铺/嵌套)、向后兼容(Style Dictionary v3)。
格式一:DTCG —— 一切的"源头"
formatters/dtcg.ts 是规范格式(canonical output)——其他所有格式理论上都能从它推导。它产出 W3C Design Tokens 标准的 JSON,有三个值得注意的细节:
| 细节 | 处理方式 |
|---|---|
| 多模式(Light/Dark) | 推荐按模式拆分为多个文件(splitByMode),这也是 Style Dictionary v4 和 Tokens Studio 的通行做法 |
| 非破坏性回写 | 通过$extensions["figma-console-mcp"]存储 Figma 变量 ID,其他 DTCG 工具会原样保留此字段,保证同步往返不丢信息 |
| 复合 Token | 字体排版、阴影、渐变输出为 DTCG 结构化的$value对象 |
此外还有一个dtcgDialect选项:默认legacy保证与历史输出字节级一致,可选2025启用 DTCG 2025.10 的对象化颜色/尺寸表示(转换逻辑在 dialect.ts)。
格式二:CSS 变量 —— 别名变var(),暗色模式零成本
formatters/css-vars.ts 是"从中间态到运行时"的第一种真实输出,处理了三个真实痛点:
1️⃣ 路径安全化:Figma 变量名经常出现空格、点号(如tailwind colors/purple/50),每段路径都会经过slugify归一化,变成合法的 CSS 自定义属性名--tailwind-colors-purple-50。
2️⃣ 别名保留级联语义:本地别名不解析成字面值,而是输出var(--target-token),让 CSS 原生级联继续工作——改一处,处处生效。
3️⃣ 跨库别名的"优雅降级":引用外部库变量的 Token(__library:标记)会跳过并输出注释说明原因,同时向warnings收集告警——宁可留缺口让你决策,也不生成坏 CSS。
多模式映射遵循社区惯例(selectorFor):
Default/Light→:rootDark→.dark(对齐 Tailwind 的darkMode: "class")- 其他模式 →
[data-theme="..."]
格式三:Tailwind v4 ——@theme命名空间映射
formatters/tailwind-v4.ts 适配 Tailwind v4 的 CSS-first 配置:Token 直接写入@theme inline { ... }块,构建时生成bg-primary、text-foreground等工具类。
核心是pathToTailwindName()的命名空间映射策略:
- 路径首段命中已知命名空间(
color、spacing、radius、shadow…)→ 原样输出,color/primary→--color-primary,于是bg-primary直接可用 - 未命中 → 按 Token 类型启发式补全:color 类型 →
color-*,dimension 类型 →spacing-* - 去重逻辑避免
theme.color.header这类路径生成color-theme-color-header的丑陋命名
暗色模式的处理很巧妙:主模式进@theme inline,其余模式输出到.dark/[data-theme="..."]选择器下,运行时即可切换,无需重新构建。
格式四:Tailwind v3 —— 导出时"拍平"别名
formatters/tailwind-v3.ts 的输出是一个可直接require进tailwind.config.js的 JS 文件。与 v4 最大的差异在于:Tailwind v3 构建期读取配置,没有运行时级联,所以别名必须通过resolveAliasChain在导出时解析为字面值。
它还内置了一张 v3 主题键映射表:color→colors、radius→borderRadius、text→fontSize、shadow→boxShadow…嵌套 Token 通过writeIntoTree构建成树形对象后输出,多模式 Token 则拍平到主模式(v3 的暗色方案由darkMode: 'class'自行处理)。
格式五:SCSS 变量 —— 没有级联就给你"模式 Map"
formatters/scss.ts 输出$ds-color-primary: #4085F2;形式的变量。由于 SCSS 变量没有运行时时换能力,它提供了两种多模式方案:
splitByMode: true→ 每个模式一个文件- 单文件模式 → 主值输出为普通变量,其余模式打包成 map(
$xxx--modes: ("Dark": ..., "Vibrant": ...)),消费方用map-get取值
其余格式:各有所长
| 格式 | 文件 | 特点 |
|---|---|---|
| TS 模块 | ts-module.ts | 输出as const常量 +Tokens类型,别名导出时解析为字面值;跨库别名输出null加 TODO 注释让缺口显性化 |
| JSON 平铺/嵌套 | json.ts | 不带 DTCG 外壳的纯键值对,供自定义构建脚本使用;多模式用--<mode>后缀拍平 |
| Style Dictionary v3 | style-dictionary-v3.ts | 裸value/type字段(无$前缀),并做 v3 与 DTCG 的类型名映射,照顾存量项目 |
| Tokens Studio | tokens-studio.ts | 多文件布局($themes.json、$metadata.json、按集合拆分),保留 Figma 绑定以支持插件"send to Figma" |
| Less | less.ts | 目前是明确的占位实现(抛出FormatterNotImplementedError),路线图占位 |
横切机制:别名解析器是整个引擎的"胶水"
所有格式器共享 alias-resolver.ts 提供的三件套:
buildTokenIndex—— 全文档 Token 索引。注意是全文档而非当前文件,因为别名经常跨集合引用(语义层 → 原子层)referenceTargetPath—— 解析带集合限定的引用{set-slug.path}resolveAliasChain—— 沿别名链一直追到字面值(供 v3/TS/JSON 这类"构建期求值"格式使用)
不同格式对别名的策略差异,正是理解这个引擎的钥匙:运行时格式(CSS 变量、Tailwind v4、SCSS)保留引用语义,构建期格式(Tailwind v3、TS、JSON)导出时求值——同一个中间态,两套哲学。
拆分策略:splitByMode×splitByCollection
每种格式都统一支持两个正交开关,组合出四种文件布局:
单文件 │ 按模式拆分 │ 按集合拆分 │ 双重拆分 全量 │ 每个模式一个文件 │ 每个集合一个文件 │ (集合×模式) 每对一个文件文件名由slugify(集合名) + slugify(模式名)动态拼接(如semantic.dark.css),也可通过filename选项显式指定。FormatResult.files返回文件数组而非单一字符串,是这个"多文件一等公民"设计的体现。
上手体验:配置 MCP 后一句话导出
在 AI 客户端中配置好figma-console-mcp后,你只需要告诉 AI "把当前 Figma 文件的 Token 导出为 Tailwind v4 格式",figma_export_tokens工具就会跑完 提取 → 转换 → 格式化 → 写文件 的全链路,并返回 warnings 列表提示被跳过的跨库别名。更多工具用法可参考 docs/tools.md,架构背景见 docs/architecture.md。
小结:这个引擎做对了什么?
- 单一中间态:
TokenDocument让 12 种格式各自独立演化 - 策略外置:别名解析时机(运行时 vs 构建期)由各格式自决,而非一刀切
- 失败显性化:warnings 收集 + 注释占位,坏 Token 不会静默污染产物
- 字节级兼容意识:
legacy方言保证升级不破坏既有产物
如果你想给项目加一种新格式,只需要在 formatters/ 下写一个纯函数、在ExportFormat类型和format()分发器中注册即可——never穷尽检查会替你把关,这就是这套架构最大的工程红利 🚀
【免费下载链接】figma-console-mcpYour design system as an API. Connect AI to Figma for extraction, creation, and debugging.项目地址: https://gitcode.com/gh_mirrors/fi/figma-console-mcp
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考