onCss:让 AI 生成 UI 代码,再把预览关进 iframe
一个 Vue 3 + Express 的 AI UI 生成器,如何用结构化 schema、mock 模式和 iframe 预览控制不确定性。
本文目录
onCss 是一个可视化 CSS / UI 代码生成工具。用户选择技术栈、组件类型和视觉风格,输入自然语言需求,后端调用 AI 生成结构化代码,前端在编辑器里展示并在 iframe 中预览。
它吸引我的地方不是“AI 写页面”,而是它把生成结果约束成一组可校验的文件,而不是一段不可执行的聊天文本。
一次生成的完整链路
前端表单
→ POST /api/generate-code
→ Zod 校验请求参数
→ AI_MODE=mock ? mockGenerator
: promptBuilder → AI → parseAiJson → Zod
→ 统一 data
→ CodeMirror 展示 / iframe 预览
后端只做一件事:代理 AI,并把结果变成稳定结构。它不存历史记录,不做用户系统,也不在线构建项目。历史记录放在前端 localStorage,预览由前端 iframe 承担。
这个边界让 MVP 很容易替换模型:只要返回结构不变,前端不需要关心背后是 DeepSeek、其他 OpenAI-compatible 服务,还是本地 mock。
为什么要求 JSON,而不是直接返回代码
如果让模型自由返回一段 Markdown,前端就要猜哪段是 Vue、哪段是 CSS、入口文件是哪个。onCss 的响应结构明确到文件级:
frameworkstyleLibrarycomponentTypetitle/descriptionfiles[]:filename、language、codepreviewEntrynotes[]
后端用 Zod 校验 AI 返回的 JSON,解析失败或结构不符就返回 AI_RESPONSE_INVALID。这不是为了“类型好看”,而是为了让前端可以安全地渲染编辑器、下载文件和选择预览入口。
mock 模式不是玩具
AI_MODE=mock 时不调用外部 API,直接返回本地生成结果。它的价值在于:
- 没有 API Key 也能调试前端表单、编辑器和预览。
- CI 可以稳定测试接口,不依赖模型输出。
- 真实 AI 失败时,至少有一个可预期的最小响应。
后端配置里 AI_MODE 默认就是 mock。对个人项目来说,这比“必须先配置 Key 才能启动”更友好。
iframe 预览的安全边界
生成的是可执行 HTML/CSS/JS。把这段内容直接注入主页面,会带来样式污染和脚本风险;放进 iframe 至少建立了文档边界。
仍需要注意:
- iframe 应使用 sandbox,按需要开放
allow-scripts,不要同时开放allow-same-origin。 - 预览内容不会自动获得主站权限。
- 代码下载和复制只处理生成的文件,不要把用户输入拼进可执行上下文。
- 后端错误信息不要回传 API Key、完整 Prompt 或内部堆栈。
这些是生成式 UI 工具的基本边界,不是可选的“安全加固”。
技术栈与取舍
| 层 | 技术 |
|---|---|
| 前端 | Vue 3 + TypeScript + Vite + Pinia + CodeMirror 6 |
| 后端 | Node.js + Express + TypeScript |
| AI | OpenAI-compatible API |
| 预览 | iframe + 前端拼装 |
第一版不做的能力也很明确:数据库、账号、项目管理、在线构建、多模型调度、额度系统。对一个小工具来说,这些“以后再说”比提前做架构更重要。
小结
onCss 的工程价值在于把 AI 的不确定性收进三个盒子:结构化请求、JSON schema、iframe 预览。模型仍然可能生成错误代码,但错误至少是可定位、可编辑、可替换的。
如果你在做类似的生成工具,先定义输出结构,再选模型;反过来通常会得到一堆无法自动处理的“看起来像代码”的文本。
讨论
评论由 GitHub Discussions 提供,点击后加载。未加载前不会产生第三方请求。