📌 1. 当前问题:AI 生成前端代码陷阱
1.1 陷阱:导致技术债
如果工程师仅仅将 AI 视为一个"更快的切图仔",直接丢给它一个 Figma 链接并要求"生成代码",其结果往往是灾难性的。这种看似高效的"一键生成",实则是在通过高利贷的方式借入技术债务。
1.2 根本原因
- AI倾向于过度拟合当前视图,忽略布局层级以及用途。
- AI缺乏全局上下文。总有些想法无法完整落在纸上(藏在你我的脑海里)。
- AI 只是"读取"当前值,而非"映射"到系统变量。
- 设计稿通常只画"最理想状态",AI无法准确预判设计缺陷以及解决方案。
📌 2. 解决方案:架构前置-推行"面向工程的设计"
要解决"僵尸前端"问题,必须从源头——Figma 设计文件入手。
工作流中,Figma 不再仅仅是画图工具,它实际上成为了源代码的一部分。
设计文件的质量直接决定了生成代码的质量(Garbage In, Garbage Out)。
前端工程师必须介入设计阶段,推行"面向工程的设计"(Design for Engineering)标准。
2.1 Auto Layout—让图层的语义明确
- 设计师(或工程师自己动手)确保Figma设计稿中的所有容器都使用 Auto Layout
- 语义化命名:图层名称是 AI 理解语义的关键线索。
将图层命名为Rectangle 54对 AI 毫无意义,但命名为SubmitBtn_Background或MainNavigation_Container则能极大地引导 AI 选择正确的 HTML 标签(如<button>或<nav>)。
2.2 定义清晰的变量(Variables)——让变量的语义明确
- 设计师定义好变量:Figma MCP 提供了
get_variable_defs功能,允许AI读取设计文件中定义的所有变量。 - 工程师用好提示词:在提示词中建立映射规则。例如:"设计文件中的变量
sys-color-surface对应 Tailwind 配置中的bg-surface"。如果不做这一步,AI 会读取变量的解析值(Resolved Value,即 hex 码)并直接写入代码,导致主题切换功能失效。 - 进阶最佳实践:在 Figma 中建立与代码库完全对应的 Token 集合,确保 AI 能够通过名称而非数值来连接设计与代码。详细阅读→Figma官方文档
2.2.1 生成Demo界面
先用能够生图的AI(或者能够生成demo HTML)生成一个demo界面,不断与AI沟通调优,最终拿到一个喜欢的方案。
现在App Demo制作的方式真的非常丰富,Figma 自己也出了新功能「Figma Make」,非常Native,非常厉害。
2.2.2 AI生成变量Json
与ChatGPT或Gemini的最强模型对话,黏贴截图,附上提示词:
提示词1(建议你第一次的时候先使用【提示词1】,充分理解了之后再使用【提示词2】或【提示词3】)
你是一个专业的设计师,非常熟悉Figma,你通读了
[[https://help.figma.com/hc/en-us/articles/18490793776023-Update-1-Tokens-variables-and-styles]],
[[https://help.figma.com/hc/en-us/articles/14548865734679-Lesson-3-Build-your-design-system#color]],
[[https://help.figma.com/hc/en-us/articles/15343816063383-Modes-for-variables#h_01KAGYPSFC984XDB4YWBCNRZJ7]]。
请你帮我的这个【UI设计demo】(如图),思考颜色主题方案,
包括了背景、按钮、等等,我不专业,所以你要非常专业,
指导我在Figma中variables 去按照你的方案设置。
提示词2
你是一个专业的设计师,非常熟悉Figma,你通读了...(省略)...
你需要输出的是分层两部分:
第一部分是思考,要简短精炼;
第二部分是表格形式的方案,方便我直接对照进行设置
提示词3(你或许需要我的json文件,可以关注并且评论"叮",拿着json文件可以更好的完善你的提示词)
你是一个专业的设计师,非常熟悉Figma,你通读了...(省略)...
你需要输出的是分层两部分:
第一部分是思考,要简短精炼;
第二部分是将方案转成可以导入Figma的Json
2.2.3 Json导入Figma
导入Figma,进行检查。如果发现不对的或不理想的,拿着Json让AI继续帮你改。
通常你会导入一个颜色方案的Json,还需要再导入一个语义方案的Json,语义方案需要使用颜色方案中的别名,别名要严格使用Figma中颜色方案的变量ID,否则会导入失败。为了拿到准确的变量ID,我们需要多做一个步骤Step 4。
2.2.4 【可选】生成语义Variables Json
此步骤是可选的,可在你有语义变量时进行。
选择Step 3(2.2.3)导入成功的Collection,右键选择Export导出Json。此时Json已经包含了所有变量的ID。把该Json扔给AI,让AI根据ID重写语义变量Collection的Json。按照这种示例编写Json:
{
"Color": {
"$type": "color",
"$value": {
"colorSpace": "srgb",
"components": [1, 1, 1],
"alpha": 1,
"hex": "#FFFFFF"
},
"$extensions": {
"com.figma.variableId": "VariableID:69:3",
"com.figma.scopes": ["ALL_SCOPES"],
"com.figma.aliasData": {
"targetVariableId": "VariableID:63:3",
"targetVariableName": "primitive/gray/0",
"targetVariableSetId": "VariableCollectionId:58:2",
"targetVariableSetName": "Color/Primitive"
}
}
},
"$extensions": { "com.figma.modeName": "Mode 1" }
}
2.2.5 【可选】巧用Code Connect UI,拒绝"组件重复造轮子"
Code Connect UI 是为了更好地服务MCP而设计的映射。能够将 Figma 库中的设计组件映射到代码库中相应的代码组件。为AI Agent提供了更好的上下文获取环境。
使用Code Connect,就相当于建立了组件的"超链接",解决了"组件重复造轮子"的问题。
使用前提:Figma升级到Organization Plan,会提示你需要工作邮箱
💡 是否需要 Code Connect?
我认为这对独立开发者或者小团队来说,ROI可能不高,原因是整套「设计稿和代码之间缺乏自动化映射」,需要的维护成本、几千块的费用成本,小团队本身沟通成本就低,Code Connect 带来的那点「对齐组织级设计系统」的加成不那么划算。
如果你还不明确自己是否需要Code Connect,你可以参考看看自己是否满足下面的条件:
- 已有稳定的设计系统 + 自研组件库
- 明确要长期运营多个产品,且都共享这套系统
- 80% 的前端工作变成「让 AI 自动按设计系统产出页面」,手写量越来越少
- 愿意为减少「AI 改错、重构」付出每年多 $400–$500 的成本 + 映射维护时间
2.3 开发者模式(Dev Mode)与注释
你可以将注释看成提示词的一部分,而且他是最好的提示词,因为他指向的UI部位特别明确。比如你可以在一个输入框旁边添加注解:"此字段需要进行Email格式校验,且在API请求期间应为Disabled状态"。
MCP 能够读取这些文本元数据,从而在生成代码时,不仅生成 UI,还能自动补全 zod 验证模式(Schema)或 disabled={isLoading} 属性。
📌 3. 重构工作流
在AI Coding 时代,全栈工程师、前端工程师的工作不再是线性的"看图 -> 写代码",UIUX设计师的工作也不再是"画图->切图->交付"。每一个人都可以身兼多职,也可以针对相互配合的MCP(为了让AI更好地参与进来)的上下文做得更好。
3.1 传统工作流 vs. MCP 增强工作流
表 3-1:工作流范式对比
| 阶段 | 传统手工工作流 | 朴素 AI 生成(照猫画虎) | MCP 增强工程化工作流 |
|---|---|---|---|
| 上下文获取 | 肉眼观察,手动测量间距,查看 Dev Mode 属性 | 截图或复制 CSS,AI 基于像素猜测 | MCP 自动提取:直接读取节点树、变量表和组件映射 |
| 代码编写 | 手写 HTML 结构,逐个调整 CSS 类名 | AI 生成单文件代码,由工程师手动拆分 | 架构先行:先定义接口和组件结构,再填充 UI,最后注入逻辑 |
| 逻辑实现 | 编写 useEffect,状态管理,API 对接 | 往往被忽略,或由工程师后续手动添加 | 逻辑分层:通过特定提示词生成 Custom Hooks 和业务逻辑层 |
| 质量控制 | 人工 Code Review,手动测试 | 依赖肉眼比对,容易遗漏隐形 Bug | 自动化验证:结合视觉回归测试(VRT)和 Lint 工具 |
3.2 核心工作流步骤详解
不要直接开始生成代码。
步骤一:让AI"理解"你的项目架构——防止"僵尸代码"的第一道防线
强迫AI进行架构思考,而不是像素堆砌
- MCP:Cursor 或 VS Code 等IDE中,或你的CLI中,确认MCP服务已连接。
- 提示词(系统级):加载
agents.md或项目特定的系统提示词(System Prompt)。包括:- 技术栈约束(React, TypeScript, Tailwind, Shadcn UI)
- 目录结构规范(Features目录 vs Component 目录)
- 设计系统路径(Token定义位置)
- 提示词(特定分析):"分析选中的 Figma Frame(或使用Figma链接:....)。识别出其中哪些部分对应我们现有的通用组件(通过 Code Connect),哪些是新的特有业务组件。请列出开发计划,不要写代码。"
步骤二:视图层生成
这一步目标是:生成无状态的、纯展示的组件。
- 输入:Figma 节点的 URL 或选中状态。
关键指令(React):
"基于 Figma 上下文生成视图组件。仅关注 UI 布局与样式。
请映射已有的 UI 组件(如有)。不要使用硬编码的像素值,
必须使用 get_variable_defs 中的 Token。
对于文本内容,请定义 Props 接口,不要写死在 JSX 中。"
产出:一个干净的 .tsx 文件,包含准确的 Tailwind 类名和语义化 HTML,但没有 useState 或 useEffect。它通过 Props 接收数据。
关键指令(SwiftUI):
"基于 Figma 上下文生成 SwiftUI 视图组件。仅关注 UI 布局与样式,
不包含业务逻辑和数据请求。如有已有的设计系统组件,请尝试复用对应的封装。
不要使用硬编码的像素值或颜色常量,必须使用 get_variable_defs 中提供的设计 Token。
对于文本内容,请通过视图的初始化参数/属性传入,不要在视图内部写死字符串。"
产出:一个干净的 .swift 文件,包含语义化的 SwiftUI 布局代码(如 VStack / HStack / ZStack / Spacer / padding 等),正确应用来自 Token 的字体、颜色和间距设置。文件中不使用 @State、@ObservedObject 等状态管理属性包装器,不包含网络请求或副作用逻辑。
步骤三:注入逻辑
我们不直接在 SwiftUI 视图组件中编写业务逻辑,而是采用 View + ViewModel,视图仅负责展示,视图模型负责状态管理、校验和数据流转。
关键指令:
"现在为上述 SwiftUI 视图组件编写一个视图模型 [ComponentName]ViewModel。
该视图模型需要处理以下工程逻辑:
1. 定义表单的数据模型和验证逻辑(根据设计图中的字段注解,约束必填、长度、格式等规则)
2. 管理加载状态和错误状态,如暴露 isLoading、errorMessage 等属性,供视图展示
3. 提供一个模拟的 API 请求方法(例如异步提交表单或拉取数据的函数)
4. 以公开属性和方法的形式向视图暴露所需的数据与操作接口"
架构意义:通过将业务逻辑从视图中剥离到 ViewModel,我们保证了视图的纯粹性和可测试性。即便界面设计大幅调整,只要 ViewModel 暴露给视图的接口(属性和方法)保持不变,业务逻辑层基本不需要修改。
步骤四:组合与布线
关键指令:
"生成一个顶层容器视图 [ComponentName]Container,
用于将 [ComponentName]ViewModel 与纯展示的 [ComponentName]View 组合起来。
容器视图内部负责创建并持有 ViewModel(例如通过 @StateObject 或 @ObservedObject),
然后将 ViewModel 暴露的状态和事件处理方法,以参数或绑定的形式传递给 View。
确保所有交互事件(如按钮点击、表单提交等)的处理函数都已正确连接到 ViewModel 中对应的方法。"
步骤五:验证与迭代
- 操作:运行代码,并使用 MCP 的
get_screenshot工具拉取设计原图进行比对。 - 关键指令:"对比生成的组件与 Figma 原图的截图。指出视觉上的差异(如间距、对齐方式)。同时,检查代码是否存在无障碍问题。"
📌 4. 提示工程,更好地指挥艺术
在使用AI给自己减负、在创造属于自己新的工作流的过程中,前端工程师的能力差异,很大程度上体现为能否写出架构级的提示词。要避免"照猫画虎",必须使用结构化、分角色的提示策略。
4.1 系统提示词 System Prompts 的设计
为了保证一致性,不应每次都手写基础规则。应在项目根目录维护一份规则文件(如 .cursor/rules 或 .mcp.json 配置),作为所有会话的基准。
表 4-1:前端架构系统提示词模板(React)
| 类别 | 提示词指令 (Instruction) | 工程目的 |
|---|---|---|
| 技术栈约束 | "Always use React Server Components where possible. Prefer clsx and tailwind-merge for class manipulation. Strictly TypeScript, no any." | 强制遵循现代技术栈最佳实践 |
| 设计系统对齐 | "Before generating new CSS, verify if a utility class or component exists in @/components/ui. Prioritize reuse over creation. Never map colors to hex codes; use CSS variables from theme.css." | 防止样式系统腐化,确保主题一致性 |
| 代码质量守门 | "All interactive elements must be keyboard accessible. Images must have dynamic alt props. Do not use nested ternaries for conditional rendering." | 强制 AI 关注无障碍和代码可读性 |
| 逻辑分离 | "Adhere to the Separation of Concerns principle. UI components must be pure. Side effects belong in Hooks or Server Actions." | 避免生成难以维护的"面条代码" |
表 4-2:iOS 架构系统提示词模板(SwiftUI)
| 类别 | 提示词指令 (Instruction) | 工程目的 |
|---|---|---|
| 技术栈约束 | "Always use Swift 6+ and SwiftUI for new UI. Prefer async/await and structured concurrency over callback-based APIs. Avoid Objective-C-only APIs unless interoperating with legacy code. Do not use force-unwrapped optionals (!) in production code." | 强制遵循现代 iOS 技术栈与并发最佳实践 |
| 设计系统对齐 | "Before creating custom colors, fonts, or spacing, verify if a token or component exists in the DesignSystem module. Prioritize reuse over creation. Never hard-code hex colors or magic numbers; always use design tokens or semantic constants." | 防止样式系统腐化,确保视觉与交互一致性 |
| 代码质量守门 | "All interactive controls must be accessible. Provide meaningful accessibilityLabel / accessibilityHint and support Dynamic Type. Prefer native controls over custom gestures for interaction. Avoid deeply nested conditionals." | 强制关注无障碍体验与代码可读性、可维护性 |
| 逻辑分离 | "Adhere to the Separation of Concerns principle using MVVM. SwiftUI Views must remain as pure as possible, focusing on layout and presentation. Side effects, networking, and business rules belong in ViewModels or dedicated services." | 避免生成难以维护的"面条代码",提升可测试性与扩展性 |
如果你有自己项目里的命名(比如你们的设计系统模块不叫 DesignSystem,而是别的名字),可以把对应那一行改成你们实际用的名字就行。
4.2 链式思维
针对复杂界面,单次提示往往失败。引导 AI 一步步思考会得到更好的效果。
- Prompt 1 (先分析): "分析这个 Figma Frame。列出它的组件层级结构,并识别出其中的重复模式(Repeating Patterns)。告诉我你会如何拆分这些视图(例如页面级视图、区块级视图和可复用的小组件)。"
—— 等待 AI 回答并确认拆分方案合理。 - Prompt 2 (Interface): "根据上述分析,定义主视图和子视图所需的 Swift 数据结构和配置类型。例如:用 struct 定义用于展示的数据模型;用 enum 定义状态或样式变体(如 enum ButtonVariant { case primary, secondary });明确每个视图通过初始化参数接收哪些属性。请完整列出这些类型和它们的属性。"
- Prompt 3 (Implementation): "现在实现这些组件视图。先从最小粒度的基础视图(按钮、标签、输入框等原子视图)开始实现,再组合成区块级视图,最后组装成完整页面。确保视图尽量保持无业务逻辑,只依赖传入的数据和回调。"
4.3 角色扮演与对抗性提示
为了测试代码的健壮性,可以让 AI 扮演 QA 的角色。
指令:
"作为一名资深 iOS QA / 代码审查工程师,审查刚刚生成的 Swift / SwiftUI 代码。
请找出其中可能导致性能问题的地方(例如在主线程上执行耗时操作、不必要的视图重绘、列表渲染不合理等),
以及可能带来内存或线程安全风险的写法(例如闭包中对 self 的强引用导致循环引用,或在非主线程更新 UI)。
同时,检查是否存在可用性和无障碍问题(如缺少合适的 accessibilityLabel、未支持 Dynamic Type)。
如果这是一个'僵尸界面'(看起来对,但交互不完整、状态不会正确更新或错误没有合理处理),
请毫不留情地指出并说明原因。"
这种自我反思机制,能显著提高代码质量。
📌 5. 质量保证与验证
即便有自动化工具,人的审查依然不可或缺,但审查重点发生了变化。
表 5-1:AI 生成代码审查清单(通用)
| 审查维度 | 关键检查点 |
|---|---|
| 幻觉检查 | 是否引入了不存在的包?是否使用了组件库中不存在的 Props? |
| 安全审计 | 是否硬编码了 API Key?用户输入是否经过了 Sanitization(消毒)? |
| 性能瓶颈 | 是否在渲染循环中进行了重计算(需用 useMemo)?是否导致了 Prop Drilling? |
| 架构一致性 | 组件粒度是否过细或过粗?是否遵循了项目目录规范? |
| 业务逻辑 | 边界情况(Edge Cases)是否处理?空状态(Empty State)是否实现? |
表 5-2:AI 生成代码审查清单(iOS/SwiftUI)
| 审查维度 | 关键检查点 |
|---|---|
| 幻觉检查 | 是否引用了工程中不存在或不推荐的框架/模块?是否使用了不存在的类型、属性或方法(例如虚构的 ViewModel、设计系统组件或样式 Token)?API 调用是否真实存在且符合当前 iOS SDK 版本? |
| 安全审计 | 是否在源码或 Info.plist 中硬编码了 API Key、密钥或其他敏感信息?日志中是否打印了用户隐私数据(如 Token、手机号、位置信息)?用户输入是否进行了必要的校验与过滤?网络请求是否强制使用 HTTPS? |
| 性能瓶颈 | 是否在主线程中执行了耗时操作(如 JSON 解析、大量计算、磁盘/网络 IO)?是否在 body 或 onAppear 中进行了不必要的重复计算或频繁网络请求?列表是否合理使用 List / LazyVStack / LazyHStack 等懒加载容器?ObservableObject / @Published 是否设计不当,导致大范围视图频繁重绘? |
| 架构一致性 | 视图粒度是否过细或过粗(巨大 View 难以维护,过度拆分又难以理解)?是否遵循项目既定的 MVVM / 模块化 / 目录结构规范?SwiftUI View 是否尽量保持"纯展示",业务逻辑是否集中在 ViewModel 或 Service 层? |
| 业务逻辑 | 边界情况(网络失败、超时、空数据、权限拒绝、API 返回异常)是否处理?空状态、加载状态、错误状态是否有对应 UI?本地化(多语言)、深色模式、无网络/弱网场景是否考虑?关键路径是否有合理的错误提示与重试机制? |
📌 6. 编排者的崛起
Figma MCP 的引入,不仅仅是工具的升级,更是前端工程师角色定义的升级。
回答用户关于"工作流"的终极问题:
如果说传统的前端工程师是"翻译官"(将设计翻译为代码),那么 AI 时代的工程师就是"指挥家"(Orchestrator)。
前端工程并没有消失,它只是向上抽象了一层。不再纠结于 margin-left 还是 padding-left,更应该关注的是组件的复用性、系统的健壮性以及用户体验的完整性。