用途
本技能用于构建复杂、多组件的 HTML 前端产物(artifact),采用现代前端技术栈。当需要制作精细的前端 artifact 时使用,触发场景包括对使用 React、Tailwind CSS、shadcn/ui 等技术的多组件 HTML 产物的请求。
主要能力
- 通过脚本初始化前端仓库,生成已配置好的 React + TypeScript(Vite)项目。
- 通过脚本将全部代码打包为单个 HTML 文件,所有 JavaScript、CSS 与依赖均内联,可直接作为 artifact 分享。
- 技术栈:React 18 + TypeScript + Vite + Parcel(打包)+ Tailwind CSS + shadcn/ui。
- 初始化生成的项目包含:React + TypeScript(Vite)、Tailwind CSS 3.4.1 与 shadcn/ui 主题系统、路径别名(@/)、40+ 预装 shadcn/ui 组件、全部 Radix UI 依赖、Parcel 打包配置(.parcelrc)、Node 18+ 兼容(自动检测并固定 Vite 版本)。
使用方式
第 1 步:初始化项目
运行初始化脚本创建新的 React 项目:
bash scripts/init-artifact.sh <project-name>
cd <project-name>
第 2 步:开发产物
编辑生成的文件来构建 artifact。
第 3 步:打包为单个 HTML 文件
bash scripts/bundle-artifact.sh
这会生成 bundle.html——一个自包含的 artifact,所有 JavaScript、CSS 和依赖均已内联。要求:项目根目录必须有 index.html。
脚本执行内容:安装打包依赖(parcel、@parcel/config-default、parcel-resolver-tspaths、html-inline);创建支持路径别名的 .parcelrc 配置;使用 Parcel 构建(无 source map);使用 html-inline 将所有资源内联为单个 HTML。
第 4 步:与用户分享产物
在对话中分享打包后的 HTML 文件,供用户作为 artifact 查看。
第 5 步:测试/可视化产物(可选)
这是完全可选的步骤,仅在必要或被要求时执行。可使用其他技能或内置工具(如 Playwright、Puppeteer)测试。一般避免提前测试,以免增加请求到成品可见之间的延迟;可在展示产物后按需测试。
设计与样式指南
编写组件前必须使用 designing-frontend-interfaces 子技能:先写设计简报并锁定 token 块。shadcn 的默认值只是起点而非设计,原样发布会产生通用化输出。发布前还需使用 designing-user-experience 覆盖状态,以及 building-accessible-interfaces 支持键盘与屏幕阅读器。
需要避免的具体“套路”特征:所有内容都居中 max-w-4xl、白底上的紫/紫罗兰→蓝色渐变、每个表面统一 rounded-lg、到处 shadow-md、以 Inter 或 system-ui 作为展示字体、text-gray-500 正文、以及 hero → 三张功能卡 → CTA 的骨架。
配置 Tailwind,而非接受默认值
Tailwind 的默认值是一套默认调色板,直接使用会让 artifact 趋同。用简报中的 token 块覆盖:
// tailwind.config.js
export default {
theme: {
extend: {
colors: {
base: "#f7f6f0", surface: "#fffffb", line: "#dcded1",
ink: { DEFAULT: "#1a271a", 2: "#4a5a46", 3: "#79876f" },
accent: { DEFAULT: "#2f6b3c", ink: "#f4fbf5" },
},
fontFamily: {
display: ['"Young Serif"', "Georgia", "serif"],
text: ['"Work Sans"', "system-ui", "sans-serif"],
},
borderRadius: { DEFAULT: "2px" }, // ONE radius
},
},
};
这样 bg-base、text-ink-2、border-line、font-display 就带有语义,主题可在一个文件中替换。applying-themes 技能提供十套经过对比度验证的调色板可直接使用。
如果选定了不同的圆角,还要禁用 shadcn 的默认圆角变量——globals.css 中的 --radius 会静默应用到每个组件。
组件与状态要求
artifact 中每个数据驱动组件都需要完整的状态集合。在自包含 artifact 中这些很容易出错,因为通常没有真实后端来强制触发。
if (error) return <ErrorState onRetry={refetch} message={...} />;
if (loading) return <Skeleton />; // matching the real layout
if (!items.length) return query ? <NoResults query={query} onClear={...} />
: <FirstRun onCreate={...} />;
return <List items={items} />;
两种空状态不同且都需要。两者都无数据是生成 artifact 中最常见的偷懒做法。
可访问性
shadcn/ui 基于 Radix,只要按预期使用其原语就是可访问的。缺陷来自你围绕它们添加的内容:
- 仅图标按钮需要 aria-label——Radix 无法推断。
- 自定义 <div onClick> 处理器会绕过 Radix 提供的一切;应使用 <Button>。
- 移除焦点环的 className 覆盖(focus:outline-none 且无替代环)会破坏键盘导航。
- 图表和画布需要文本替代——说明发现的标题。
- 主题化后验证对比度;Radix 不检查你的颜色。
性能
artifact 是单个自包含文件,因此打包体积就是全部加载时间。
- 将字体以内联 base64 woff2 形式嵌入,并按使用的字符做子集化。完整 TTF 可能超过其余打包体积的总和。
- 不要导入图标库。import { X } from "lucide-react" 可能因 tree-shaking 情况拉入整个集合。应粘贴单个 SVG。
- 超过约 200 行的列表要虚拟化。渲染数千个 DOM 节点会冻结标签页。
- 大列表中的行使用 React.memo;保持 key 稳定。
- 不要外部请求。artifact 常在阻止 CDN、远程字体和 fetch 的 CSP 下运行,所有内容必须内联。
验证
展示 artifact 前,打开 bundle.html 检查:
python3 -c "
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
b = p.chromium.launch(); pg = b.new_page(viewport={'width':1440,'height':900})
errs=[]; pg.on('console', lambda m: m.type=='error' and errs.append(m.text))
pg.on('pageerror', lambda e: errs.append(str(e)))
pg.goto('file://$PWD/bundle.html'); pg.wait_for_timeout(1200)
pg.screenshot(path='/tmp/artifact.png', full_page=True)
pg.set_viewport_size({'width':390,'height':844})
pg.screenshot(path='/tmp/artifact-mobile.png', full_page=True)
print('CONSOLE ERRORS:', errs); b.close()"
然后查看两张截图。构建成功仍可能渲染空白——缺失的内联资源、CSP 违规或懒渲染分支中的运行时错误都会产生干净构建和空白页面。
适用场景
需要构建复杂、多组件、可自包含分享的 HTML 前端产物时。
限制
- 打包要求项目根目录存在 index.html。
- 测试步骤为可选,且建议在展示产物后进行。
- 具体收费、价格、平台等信息暂未提供。
参考
shadcn/ui 组件:https://ui.shadcn.com/docs/components