D2C:前端的自我革命

序言

​ 这半个月一直在专注于 Figma-to-Code 的相关工作,也在不断思考和调研已有的 D2C(Design to Code)方案。

​ 目前市面上主流的实现方式,大多是基于 Figma 插件,通过插件调用 Figma 的 Open API 获取设计稿的结构和样式信息,再转换成对应的 DSL(中间描述语言),最终通过渲染引擎生成各端代码。也有一些方案尝试通过设计稿的截图,结合视觉识别算法实现 0 到 1 的生成,但这种方式在还原度和一致性方面存在明显短板,难以满足生产需求。

​ 这几天阅读了大量相关资料,包括公司内部方案,也参考了外部团队的一些实践。其中印象较深的有:

  • 网易云音乐技术团队的 海豹 D2C:提出了基于 DSL + 引擎驱动的完整设计转码链路,思路清晰,落地程度较高。
  • 字节跳动的 Semi Design:虽然更偏向组件体系,但其设计-开发一体化理念、设计规范约束和配套工具链也对 D2C 体系建设有很强的借鉴意义。

总体来看,D2C 的核心逻辑可以归纳为三步:

  1. 解析设计稿:通过 Figma Open API 提取结构与样式;
  2. 转换为 DSL:构建平台无关的中间描述层;
  3. 生成端代码:通过模板或引擎渲染出对应平台代码(Web / Native / Flutter 等)。

​ 虽然整体流程逐渐清晰,但受限于 Figma 本身的表达能力、设计规范一致性、插件能力边界等因素,还原度始终是当前最大的挑战,尤其在复杂交互、自适应布局、组件语义识别等方面,仍有大量细节需要补齐。

Figma API中的信息

节点类型

节点类型 说明
FRAME 框架,是Figma中最常用的容器节点(也可作为画板)。可嵌套其他节点。
GROUP 分组,用于逻辑上组合多个元素,不具备 Frame 的布局功能。
RECTANGLE 矩形,最常见的形状元素。
ELLIPSE 椭圆或圆形。
LINE 直线。
POLYGON 多边形。
STAR 星形。
VECTOR 矢量路径(Pen 工具画出的路径)。
TEXT 文本元素。

节点属性

🧱 通用基础属性(所有节点都具有)

属性 类型 说明
id string 节点的唯一 ID。
name string 节点的名称。
type string 节点的类型,如 "FRAME""TEXT" 等。
visible boolean 节点是否可见。
locked boolean 是否锁定节点。
parent BaseNode null
removed boolean 是否已从文档中移除。只读。
children SceneNode[] 子节点数组(如果节点支持包含子节点)。

🖼️ 通用场景属性(大多数可视节点具有)

属性 类型 说明
x, y number 节点相对于父节点的位置。
width, height number 节点的尺寸。
rotation number 旋转角度(度)。
relativeTransform Transform 节点相对于父节点的变换矩阵。
absoluteTransform Transform 相对于画布的变换矩阵。
constraints Constraints 自动布局的约束条件。
layoutAlign string 在自动布局中的对齐方式(如 "STRETCH""CENTER")。
layoutGrow number 在自动布局中是否可扩展。

🎨 图形样式属性(大多数图形节点具有)

属性 类型 说明
fills Paint[] 填充颜色、渐变、图片等。
strokes Paint[] 描边样式。
strokeWeight number 描边粗细。
strokeAlign string 描边对齐方式("CENTER""INSIDE""OUTSIDE")。
cornerRadius number mixed
opacity number 不透明度(0~1)。
blendMode BlendMode 混合模式。
effects Effect[] 阴影、模糊等效果。
isMask boolean 是否作为遮罩。
exportSettings ExportSettings[] 导出配置。

🔠 文本节点(TEXT)特有属性

属性 类型 说明
characters string 文本内容。
fontSize number mixed
fontName { family: string, style: string } 字体。
textAlignHorizontal string 水平对齐("LEFT""CENTER""RIGHT")。
textAlignVertical string 垂直对齐("TOP""CENTER""BOTTOM")。
lineHeight LineHeight 行高。
letterSpacing LetterSpacing 字间距。
textAutoResize string 文本自动调整尺寸方式。
textStyleId string 关联的文本样式 ID。

🧱 自动布局属性(如 FRAME, COMPONENT 等)

属性 类型 说明
layoutMode "NONE" "HORIZONTAL"
primaryAxisAlignItems string 主轴对齐方式。
counterAxisAlignItems string 交叉轴对齐方式。
itemSpacing number 子元素间距。
paddingLeft/Right/Top/Bottom number 内边距。

🧩 组件相关属性(COMPONENT, INSTANCE

属性 类型 说明
mainComponent ComponentNode INSTANCE 实例对应的组件定义。
componentPropertyReferences Record<string, string> 实例中引用的属性。
variantProperties Record<string, string> 组件变体中的属性值(在 COMPONENT_SET 中)。

全链路跑通

​ 大概用了半个月的时间,我们基于 Dify + MCP + LLM 的组合,成功打通了 D2C 的完整链路。相比市面上不少公司繁琐复杂的方案,我们的目标很简单:只做一件事------输入一个设计稿,输出所需的组件。

​ 是的,这就是我们第一阶段的 MVP。看似简单,但我们确实做到了端到端的打通。

​ 不过,现实也没有那么理想。由于底层技术方案还存在一些限制,尤其是在解析复杂结构、还原视觉细节等方面,当前方案在设计稿还原度上依然存在较大提升空间。这也是接下来需要重点攻克的方向。

​ Figma 在布局结构上的表达方式与传统 HTML 有着明显差异,尤其是在自动布局、约束关系等方面。因此,Figma API 提供的节点信息,往往无法直接映射为标准的 HTML 布局结构。

​ 在第一阶段,我们完成了从 Figma 设计稿到初步 HTML 结构的转换。随后在 HTML 向 React 组件的规范化转换中,我们进行了多轮迭代,并测试了多种大模型的表现。

​ 对比结果显示,Claude 4Gemini 2.5 Pro 在生成准确性和结构还原方面表现最优,明显优于其他同类模型。这也解释了为何一些 D2C 工具会选择集成 Claude 模型作为其底层能力------更强的代码结构理解力带来了更高的还原度和更少的人工干预。

D2C 已知痛点

1. 设计稿中存在无用图层

UI 设计师在设计过程中,往往会隐藏一些暂不使用或用于参考的图层。这些隐藏元素在视觉交付时无影响,但在解析 Figma 设计稿时仍然会被包含,导致我们在判断其是否应渲染时需额外处理层级、可见性等逻辑,增加了解析成本。

针对无用节点的排除问题,主要有两种可行方案:

  1. 人工标注:通过人工方式对设计稿中的无效元素进行标注与筛选,从源头减少冗余结构,但是会增加设计师工作量;
  2. 自动对比优化:结合大模型的图像理解能力,在 dify 流程中将设计稿作为图片输入,并与生成的 HTML 页面进行结构和视觉对比,从而自动调整 HTML 布局,优化输出结果。

2. 图层是否需要整体导出为图片

在遇到复杂图层结构(如多个图层交错、遮罩、混合模式等)时,直接还原为代码会增加实现难度和不确定性。此类场景下,若能自动识别并将其作为整体导出为一张图片,会显著简化开发流程。

graph TD A[开始 isSVG node] --> A1{是否有子节点}; A1 -- 否 --> Z1[返回 false]; A1 -- 是 --> B{是否有可见子孙节点}; B -- 否 --> C[返回 false]; B -- 是 --> D{isSVGOld 判断}; D -- 是 --> E[返回 true - 作为 SVG 导出]; D -- 否 --> F[返回 false - 不作为 SVG 导出]; subgraph isSVGOld G[开始 isSVGOld node] --> H{名称包含 #no-merge#}; H -- 是 --> I[返回 false]; H -- 否 --> J{名称包含 #merge#}; J -- 是 --> K[返回 true]; J -- 否 --> L{是否基本图形类型}; L -- 是 --> K; L -- 否 --> M{是否容器类型}; M -- 否 --> I; M -- 是 --> N{子节点是否完全相交}; N -- 是 --> O{所有子节点 isSVGOld 也为 true}; O -- 是 --> K; O -- 否 --> I; N -- 否 --> P{所有子节点为 VECTOR 或 ASSET}; P -- 是 --> K; P -- 否 --> I; end Z1 --> Z[结束]; C --> Z; E --> Z; F --> Z;

3. 无响应式布局信息

Figma 原生输出的信息大多是基于绝对像素(px)的定位和尺寸,没有包含响应式布局的语义。这对需要适配不同屏幕的 Web 端开发非常不友好,若无后续处理,将导致导出的代码缺乏灵活性和扩展性。

总结

​ 周参与了公司内部关于 Figma 的邀请制会议。Figma 官方计划在未来几个月正式发布 MCP,这意味着相较于我们当前基于第三方方案所开发的 MCP,官方版本在还原度、交互细节及整体稳定性方面将具有显著优势。这也意味着,我们近期投入的相关工作很可能在未来被替代。

​ 尽管如此,这段过程依然收获颇丰。通过实践,我不仅深入理解了设计到代码转换的技术路径,也重新激发了初学时那种不断探索与攻克难点的热情。某种程度上,这段经历更像是一场自我打磨与能力进阶。

相关推荐
仟濹2 小时前
【HTML】基础学习【数据分析全栈攻略:爬虫+处理+可视化+报告】
大数据·前端·爬虫·数据挖掘·数据分析·html
小小小小宇4 小时前
前端WebWorker笔记总结
前端
小小小小宇4 小时前
前端监控用户停留时长
前端
小小小小宇4 小时前
前端性能监控笔记
前端
烛阴4 小时前
Date-fns教程:现代JavaScript日期处理从入门到精通
前端·javascript
全栈小55 小时前
【前端】Vue3+elementui+ts,TypeScript Promise<string>转string错误解析,习惯性请出DeepSeek来解答
前端·elementui·typescript·vue3·同步异步
穗余5 小时前
NodeJS全栈开发面试题讲解——P6安全与鉴权
前端·sql·xss
穗余6 小时前
NodeJS全栈开发面试题讲解——P2Express / Nest 后端开发
前端·node.js
航Hang*6 小时前
WEBSTORM前端 —— 第3章:移动 Web —— 第4节:移动适配-VM
前端·笔记·edge·less·css3·html5·webstorm
江城开朗的豌豆6 小时前
JavaScript篇:a==0 && a==1 居然能成立?揭秘JS中的"魔法"比较
前端·javascript·面试