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 的响应结构明确到文件级:

  • framework
  • styleLibrary
  • componentType
  • title / description
  • files[]:filename、language、code
  • previewEntry
  • notes[]

后端用 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
AIOpenAI-compatible API
预览iframe + 前端拼装

第一版不做的能力也很明确:数据库、账号、项目管理、在线构建、多模型调度、额度系统。对一个小工具来说,这些“以后再说”比提前做架构更重要。

小结

onCss 的工程价值在于把 AI 的不确定性收进三个盒子:结构化请求、JSON schema、iframe 预览。模型仍然可能生成错误代码,但错误至少是可定位、可编辑、可替换的。

如果你在做类似的生成工具,先定义输出结构,再选模型;反过来通常会得到一堆无法自动处理的“看起来像代码”的文本。

讨论

评论由 GitHub Discussions 提供,点击后加载。未加载前不会产生第三方请求。