前面有提到过, Figma Make 在技术选型上实施了一套分层约束体系, 既允许特定范围的灵活性(如安装 three.js),又明确拒绝某些框架(如 Next.js)。 今天探讨这套约束背后的逻辑。
这种设计反映了两个核心点,
-
1. 底层架构的根本限制, -
2. 该产品的产品定位。
本文从六个层面来讨论。
第一层:运行时架构约束(Runtime Architecture Constraints)
Figma Make 的根本约束来自其浏览器内 JavaScript 运行时的本质,这是他的核心限制(纯客户端浏览器运行时):
-
• 基于浏览器的 Node.js 模拟环境 -
• 运行在隔离的 iframe 沙箱中 -
• 所有代码执行都在客户端(无服务器进程) -
• 使用 Vite 作为打包和热重载引擎 -
• 通过 ESM (ES Modules) 动态加载依赖
为什么可以支持 React + Vite?
React 和 Vite 这个组合完全符合客户端运行时模型:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
为什么拒绝 Next.js?
Next.js 的核心价值在于服务器端功能,这与 Figma Make 的架构根本冲突:
Next.js 的服务器依赖特性:
├─ Server Components(React Server Components)
├─ Server-Side Rendering (SSR)
├─ Static Site Generation (SSG)
├─ API Routes(/pages/api/*)
├─ Middleware(边缘计算)
├─ Image Optimization(需要服务器处理)
├─ 动态路由(需要服务器路由器)
└─ 增量静态再生(ISR)
所有这些功能都需要 Node.js 服务器进程,而 Figma Make 只有浏览器环境。
即使技术上可以运行 Next.js 的客户端部分(如使用 Pages Router 的纯静态导出),这也会:
-
1. 误导用户:用户期望 Next.js 的完整功能,但 90% 的特性无法工作 -
2. 破坏开发体验:代码在 Make 中运行,但部署到真实环境时完全失效 -
3. 增加支持负担:大量用户会报告"Next.js 不工作"的问题
因此,Figma 主动明确拒绝 Next.js,而不是让用户陷入功能陷阱。
第二层:依赖管理约束(Dependency Management Constraints)
Figma Make 通过特殊的依赖解析系统支持动态安装包,同时也锁定了支持的 npm 包类型:
下面是 Figma 导出的代码:
// Figma Make 的导入语法(带版本标记)
import React from 'react@18.2.0';
import * as THREE from 'three@0.160.0';
import { Button } from '@radix-ui/react-button@1.1.3';
其运行时处理流程大致如下:
-
1. 拦截 import 语句 -
2. 从 npm 注册表或 ESM CDN (如 esm.sh、unpkg) 动态加载 -
3. 缓存到浏览器内存 -
4. 注入到沙箱环境
支持的包类型
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
不支持的包类型
下面这些包会被拒绝,或者无法工作:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
three.js 为什么可以工作?
three.js 作为一个 3d 库,看起来很复杂,但 three.js 完全基于 WebGL,这是浏览器的原生 API:
// three.js 的运行模型
import * as THREE from 'three';
const scene = new THREE.Scene();
const renderer = new THREE.WebGLRenderer();
// ↑ 直接调用浏览器的 WebGL API
// 完全在客户端渲染,无需服务器
document.body.appendChild(renderer.domElement);
第三层:框架与组件库约束(Framework and Library Constraints)
shadcn/ui 在 figma make 系统里有特殊地位, 已经被 内置到 Figma Make 的默认生成模板 中, 对设计系统和组件的有限支持,也是其完成高质量原型实现的一个重要因素。
因为对于 shadcn/ui 可以进行有指向性的预训练,这些预训练可能包括:
-
• shadcn/ui 的所有 51+ 组件 -
• Radix UI 原语(shadcn 的底层依赖) -
• Tailwind CSS 变量和令牌 -
• 常见的 shadcn 使用模式
生成代码时自动引用:
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
为什么选择 shadcn/ui?
除了流行,shadcn/ui 也有一些对 AI 友好的特性:
-
1. 无运行时开销:shadcn 不是 npm 包,而是可复制的代码片段 -
2. Tailwind 原生:与 Make 的 Tailwind 编译管道完美集成 -
3. 设计系统友好:易于自定义和扩展 -
4. 社区支持:大量 Figma 设计文件与之对应
用户自定义组件库的限制
当前 Figma Make 不支持私有 npm 包的主要障碍有两点:技术支持和实现挑战。
缺失的技术支持:
-
1. .npmrc 文件读取(npm 认证配置) -
2. 私有注册表解析(如 GitHub Packages、npm Enterprise) -
3. 作用域包认证(@company/package)
技术实现挑战:
-
• 浏览器环境无法安全存储 npm 认证令牌 -
• 需要代理服务器处理私有包请求 -
• 与 Figma 的安全模型冲突
这是是一个已知的限制,并在路线图上,但需要重大架构改进。也就是说哪一天能看到完全看 Figma 心情。
第四层:代码生成约束(Code Generation Constraints)
Figma Make 的 LLM 模型被明确训练和约束为生成特定技术栈, 把 React + TypeScript + Tailwind 作为强制标准。
// 生成的代码总是遵循这个模板
importReact, { useState, useEffect } from'react';
import'./output.css'; // Tailwind 编译输出
exportfunctionComponentName() {
// React Hooks 状态管理
const [state, setState] = useState(initialValue);
return (
<div className="tailwind-classes">
{/* JSX 结构 */}
</div>
);
}
为什么不支持 Vue/Angular/Svelte?
虽然技术上可以训练模型生成其他框架代码,但存在多重限制:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
具体技术障碍:
// Vue 的单文件组件需要特殊编译器
<template>
<div>{{ message }}</div>
</template>
<scriptsetup>
const message = ref('Hello');
</script>
// ↑ 浏览器无法直接执行,需要 vue-loader
// Angular 需要 TypeScript 装饰器和 AOT 编译
@Component({ selector: 'app-root' })
exportclassAppComponent { }
// ↑ 需要完整的 Angular 编译管道
// Svelte 需要编译器将 .svelte 文件转换为 JS
<script>
let count = 0;
</script>
<buttonon:click={() => count++}>{count}</button>
// ↑ 浏览器无法直接运行
React 的 JSX 可以通过 esbuild 在浏览器中实时转译,这是 Make 能支持它的关键原因。
第五层:需求响应的智能决策系统(Request Handling Intelligence)
Figma Make 的 AI 系统被 明确注入了约束意识,系统提示词大约如下:
你是 Figma Make 的代码生成助手。
技术栈约束(强制):
- 框架:React 18+(必须)
- 语言:TypeScript 或 JavaScript
- 样式:Tailwind CSS(优先)或 CSS Modules
- 组件库:shadcn/ui(默认)
- 构建工具:Vite(固定)
明确禁止:
- ❌ Next.js, Nuxt, SvelteKit(需要服务器)
- ❌ 服务器端渲染(SSR)
- ❌ API 路由(/api/*)
- ❌ 文件系统操作
- ❌ 数据库连接
允许的外部库:
- ✅ 纯客户端 npm 包(three.js, d3.js, etc.)
- ✅ React 组件库(Radix UI, MUI, etc.)
- ✅ 状态管理(zustand, jotai, etc.)
当用户请求不支持的技术时:
1. 礼貌解释技术限制
2. 提供可行的替代方案
3. 如果可能,用客户端方案实现相同目标
实际对话示例分析
场景 1:用户请求 "使用 Next.js 创建这个页面"
AI 的响应逻辑:
┌─────────────────────────────────────────┐
│ 1. 检测到 "Next.js" 关键词 │
│ 2. 触发约束检查:Next.js = 禁止 │
│ 3. 生成拒绝响应 + 替代方案 │
└─────────────────────────────────────────┘
生成的回复(推测):
"我理解你希望使用 Next.js,但 Figma Make 目前
仅支持纯客户端 React 应用。Next.js 的服务器功能
(SSR、API routes)在浏览器运行时中不可用。
我可以为你创建一个功能相同的 React + Vite 应用,
它将使用客户端路由(React Router)来实现导航。
你可以稍后将代码迁移到 Next.js 项目中。"
场景 2:用户请求 "安装 three.js 创建 3D 场景"
AI 的响应逻辑:
┌─────────────────────────────────────────┐
│ 1. 检测到 "three.js" │
│ 2. 约束检查:客户端库 = 允许 │
│ 3. 生成安装 + 使用代码 │
└─────────────────────────────────────────┘
生成的代码:
import * as THREE from 'three@0.160.0';
import { useEffect, useRef } from 'react';
export function Scene3D() {
const mountRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75,
window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
// ... 完整的 three.js 设置
return () => renderer.dispose();
}, []);
return <div ref={mountRef} />;
}
场景 3:用户请求 "使用 Prisma 连接数据库"
AI 的响应逻辑:
┌─────────────────────────────────────────┐
│ 1. 检测到 "Prisma" + "数据库" │
│ 2. 约束检查:数据库客户端 = 禁止 │
│ 3. 提供客户端替代方案 │
└─────────────────────────────────────────┘
生成的回复(推测):
"Figma Make 运行在浏览器中,无法直接连接数据库
(这需要服务器环境)。
替代方案:
1. 使用外部 API:调用现有的 REST/GraphQL API
2. 使用 Firebase/Supabase:客户端 SDK 可在浏览器中工作
3. 模拟数据:使用本地 state 或 localStorage 进行原型测试
我可以帮你设置其中任何一种方案。"
第六层:代码导出与本地开发的断层(Export Gap)
下载的代码可以直接运行,但是需要手动调整才能在比较符合传统的工程习惯。 不过这也验证了前面我们说的「产品定位」,Make 作为原型工具,而不是专业编码工具。
|
|
|
|
|
|
|
import X from 'lib@1.2.3' |
import X from 'lib' |
|
|
|
|
|
|
|
|
|
.env
|
|
|
|
|
|
|
当然上面的问题都容易解决,使用任意一个 AI 编辑器,都很容易修复。
总结:设计哲学与技术权衡
LLM 大模型的竞争已经不是一般公司能参与的了。 但是在应用领域,每家企业都可以把自己在这个领域的积累 和 AI 能力相融合,做好产品定位, 推出行业内、有特色的先进产品。
Figma Make 的约束体系就很好的反映了其深思熟虑的产品定位,值得我们的学习和参考。 总结一下 Figma Make 的核心设计哲学:
-
1. 简单性优先:选择最小可行技术栈(React + Vite + Tailwind) -
2. 即时性保证:浏览器运行时确保毫秒级预览刷新,给用户最好的用户体验 -
3. 安全性边界:避免服务器代码执行的安全风险 -
4. 成本控制:无需为每个项目维护云端容器实例,保持低运行成本 -
5. 用户期望管理:明确拒绝而非半残功能,避免用户混淆
总之,Make 的约束系统是故意为之的工程决策,而非技术能力不足。它选择了一个狭窄但深入的技术范围,在这个范围内提供卓越体验,而不是试图支持所有框架但每个都做得平庸。
这种设计与 Figma 本身的哲学一致:在特定领域做到极致,而不是成为万能工具。

