Skip to content

7.8 Web Artifacts Builder - 构建复杂 Web Artifacts

概述

Web Artifacts Builder 是一个用于创建复杂、多组件的 claude.ai HTML artifacts 的工具套件。它使用现代前端技术栈(React、Tailwind CSS、shadcn/ui)来构建功能强大的交互式 Web 应用。

适用场景

这个 Skill 适用于需要以下功能的复杂 artifacts:

  • 状态管理(React hooks)
  • 路由功能
  • shadcn/ui 组件库
  • 多组件交互

注意:对于简单的单文件 HTML/JSX artifacts,不需要使用此 Skill。

技术栈

+------------------+------------------+------------------+
|     框架层       |     样式层        |     工具层       |
+------------------+------------------+------------------+
| React 18         | Tailwind CSS     | Vite            |
| TypeScript       | shadcn/ui        | Parcel (打包)   |
| Radix UI         | CSS Variables    | pnpm            |
+------------------+------------------+------------------+

工作流程

创建 Web Artifact 的完整流程:

+------------+     +------------+     +------------+     +------------+     +------------+
|   Step 1   | --> |   Step 2   | --> |   Step 3   | --> |   Step 4   | --> |   Step 5   |
+------------+     +------------+     +------------+     +------------+     +------------+
| 初始化项目 |     | 开发应用   |     | 打包成HTML |     | 展示给用户 |     | 测试(可选) |
| init-      |     | 编辑代码   |     | bundle-    |     | 分享       |     | Playwright |
| artifact   |     | 添加组件   |     | artifact   |     | artifact   |     | Puppeteer  |
+------------+     +------------+     +------------+     +------------+     +------------+

Step 1: 初始化项目

使用初始化脚本创建新的 React 项目:

bash
bash scripts/init-artifact.sh <project-name>
cd <project-name>

脚本功能

初始化脚本会自动完成以下配置:

功能说明
React + TypeScript通过 Vite 创建
Tailwind CSS 3.4.1配置 shadcn/ui 主题系统
路径别名 (@/)已配置
shadcn/ui 组件40+ 组件预装
Radix UI 依赖全部包含
Parcel 配置通过 .parcelrc 配置打包
Node 18+ 兼容自动检测并固定 Vite 版本

自动安装的组件

项目初始化后,以下 shadcn/ui 组件已预装:

基础组件:
  accordion, alert, aspect-ratio, avatar, badge, breadcrumb
  button, card, checkbox, collapsible, input, label
  separator, skeleton, textarea, toggle

交互组件:
  calendar, carousel, command, context-menu, dialog
  drawer, dropdown-menu, hover-card, menubar
  navigation-menu, popover, select, sheet

表单组件:
  form, radio-group, slider, switch

展示组件:
  progress, scroll-area, table, tabs, toast, sonner
  resizable, toggle-group, tooltip

Step 2: 开发应用

项目结构

初始化后的项目结构:

project-name/
|-- index.html           # 入口 HTML
|-- package.json
|-- vite.config.ts       # Vite 配置(含路径别名)
|-- tailwind.config.js   # Tailwind 配置(含 shadcn 主题)
|-- postcss.config.js
|-- tsconfig.json
|-- components.json      # shadcn/ui 配置
|-- src/
    |-- index.css        # Tailwind 指令 + CSS 变量
    |-- main.tsx         # React 入口
    |-- App.tsx          # 主应用组件
    |-- components/
        |-- ui/          # shadcn/ui 组件
            |-- button.tsx
            |-- card.tsx
            |-- dialog.tsx
            |-- ...
    |-- lib/
        |-- utils.ts     # cn() 工具函数

导入组件

tsx
// 导入 UI 组件
import { Button } from '@/components/ui/button'
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card'
import { Dialog, DialogContent, DialogTrigger } from '@/components/ui/dialog'

// 导入图标
import { Plus, Settings, Search } from 'lucide-react'

使用 CSS 变量主题

Tailwind 配置使用 CSS 变量实现主题系统:

css
/* 亮色主题 */
:root {
  --background: 0 0% 100%;
  --foreground: 0 0% 3.9%;
  --primary: 0 0% 9%;
  --primary-foreground: 0 0% 98%;
  --secondary: 0 0% 96.1%;
  --muted: 0 0% 96.1%;
  --accent: 0 0% 96.1%;
  --destructive: 0 84.2% 60.2%;
  --border: 0 0% 89.8%;
  --ring: 0 0% 3.9%;
  --radius: 0.5rem;
}

/* 暗色主题 */
.dark {
  --background: 0 0% 3.9%;
  --foreground: 0 0% 98%;
  --primary: 0 0% 98%;
  --primary-foreground: 0 0% 9%;
  /* ... */
}

开发服务器

bash
pnpm dev

Step 3: 打包成单一 HTML 文件

开发完成后,将 React 应用打包成单一 HTML artifact:

bash
bash scripts/bundle-artifact.sh

打包过程

脚本执行以下步骤:

  1. 安装打包依赖

    • parcel
    • @parcel/config-default
    • parcel-resolver-tspaths
    • html-inline
  2. 创建 Parcel 配置(如果不存在)

    json
    {
      "extends": "@parcel/config-default",
      "resolvers": ["parcel-resolver-tspaths", "..."]
    }
  3. 使用 Parcel 构建

    bash
    pnpm exec parcel build index.html --dist-dir dist --no-source-maps
  4. 内联所有资源

    bash
    pnpm exec html-inline dist/index.html > bundle.html

输出

脚本生成 bundle.html——一个自包含的 artifact,所有 JavaScript、CSS 和依赖都已内联。这个文件可以直接在 Claude 对话中作为 artifact 分享。

Step 4: 展示给用户

将打包好的 HTML 文件作为 artifact 分享给用户,让他们可以直接在 Claude 对话中查看和交互。

Step 5: 测试(可选)

这是一个可选步骤,仅在必要时或用户请求时执行。

可以使用以下工具测试 artifact:

  • Playwright
  • Puppeteer
  • 其他 Skills 或内置工具

最佳实践:避免预先测试 artifact,因为这会增加请求和用户看到成品之间的延迟。先展示 artifact,如果有问题或用户请求再测试。

设计指南

避免 "AI Slop" 美学

非常重要:为避免被称为 "AI slop" 的通用 AI 生成风格,请避免:

避免替代方案
过度居中布局使用不对称布局、网格系统
紫色渐变使用独特的配色方案
统一圆角混合使用不同圆角或直角
Inter 字体选择有特色的字体

设计建议

  1. 排版:选择独特、有个性的字体组合
  2. 颜色:创建有凝聚力的配色方案,避免陈词滥调
  3. 布局:尝试不对称布局、重叠元素、网格打破
  4. 动效:使用有意义的过渡和微交互

实际应用示例

示例 1: 待办事项应用

bash
# 初始化项目
bash scripts/init-artifact.sh todo-app
cd todo-app
tsx
// src/App.tsx
import { useState } from 'react'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card'
import { Checkbox } from '@/components/ui/checkbox'
import { Plus, Trash2 } from 'lucide-react'

interface Todo {
  id: number
  text: string
  completed: boolean
}

export default function App() {
  const [todos, setTodos] = useState<Todo[]>([])
  const [input, setInput] = useState('')

  const addTodo = () => {
    if (!input.trim()) return
    setTodos([...todos, { id: Date.now(), text: input, completed: false }])
    setInput('')
  }

  const toggleTodo = (id: number) => {
    setTodos(todos.map(todo =>
      todo.id === id ? { ...todo, completed: !todo.completed } : todo
    ))
  }

  const deleteTodo = (id: number) => {
    setTodos(todos.filter(todo => todo.id !== id))
  }

  return (
    <div className="min-h-screen bg-background p-8">
      <Card className="max-w-md mx-auto">
        <CardHeader>
          <CardTitle>Todo List</CardTitle>
        </CardHeader>
        <CardContent>
          <div className="flex gap-2 mb-4">
            <Input
              value={input}
              onChange={(e) => setInput(e.target.value)}
              placeholder="Add a task..."
              onKeyDown={(e) => e.key === 'Enter' && addTodo()}
            />
            <Button onClick={addTodo}>
              <Plus className="h-4 w-4" />
            </Button>
          </div>
          <div className="space-y-2">
            {todos.map(todo => (
              <div key={todo.id} className="flex items-center gap-2">
                <Checkbox
                  checked={todo.completed}
                  onCheckedChange={() => toggleTodo(todo.id)}
                />
                <span className={todo.completed ? 'line-through text-muted-foreground' : ''}>
                  {todo.text}
                </span>
                <Button variant="ghost" size="sm" onClick={() => deleteTodo(todo.id)}>
                  <Trash2 className="h-4 w-4" />
                </Button>
              </div>
            ))}
          </div>
        </CardContent>
      </Card>
    </div>
  )
}
bash
# 打包
bash scripts/bundle-artifact.sh

示例 2: 数据仪表板

tsx
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card'
import { Progress } from '@/components/ui/progress'
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'

export default function Dashboard() {
  return (
    <div className="min-h-screen bg-background p-8">
      <h1 className="text-3xl font-bold mb-8">Analytics Dashboard</h1>

      <div className="grid grid-cols-1 md:grid-cols-3 gap-4 mb-8">
        <Card>
          <CardHeader>
            <CardTitle className="text-sm">Total Users</CardTitle>
          </CardHeader>
          <CardContent>
            <p className="text-3xl font-bold">12,345</p>
            <p className="text-sm text-muted-foreground">+12% from last month</p>
          </CardContent>
        </Card>
        {/* 更多卡片... */}
      </div>

      <Tabs defaultValue="overview">
        <TabsList>
          <TabsTrigger value="overview">Overview</TabsTrigger>
          <TabsTrigger value="analytics">Analytics</TabsTrigger>
          <TabsTrigger value="reports">Reports</TabsTrigger>
        </TabsList>
        <TabsContent value="overview">
          <Card>
            <CardContent className="pt-6">
              <Progress value={75} className="mb-2" />
              <p className="text-sm text-muted-foreground">75% of monthly goal</p>
            </CardContent>
          </Card>
        </TabsContent>
        {/* 更多标签内容... */}
      </Tabs>
    </div>
  )
}

常用组件速查

按钮变体

tsx
<Button>Default</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="destructive">Destructive</Button>
<Button variant="outline">Outline</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="link">Link</Button>

对话框

tsx
<Dialog>
  <DialogTrigger asChild>
    <Button>Open Dialog</Button>
  </DialogTrigger>
  <DialogContent>
    <DialogHeader>
      <DialogTitle>Title</DialogTitle>
      <DialogDescription>Description</DialogDescription>
    </DialogHeader>
    {/* 内容 */}
    <DialogFooter>
      <Button>Save</Button>
    </DialogFooter>
  </DialogContent>
</Dialog>

下拉菜单

tsx
<DropdownMenu>
  <DropdownMenuTrigger asChild>
    <Button variant="outline">Options</Button>
  </DropdownMenuTrigger>
  <DropdownMenuContent>
    <DropdownMenuItem>Profile</DropdownMenuItem>
    <DropdownMenuItem>Settings</DropdownMenuItem>
    <DropdownMenuSeparator />
    <DropdownMenuItem>Logout</DropdownMenuItem>
  </DropdownMenuContent>
</DropdownMenu>

参考资源

总结

Web Artifacts Builder 提供了一套完整的工具链来创建复杂的 Web artifacts:

  1. 快速初始化:一键创建完整配置的 React + TypeScript + Tailwind + shadcn/ui 项目
  2. 丰富的组件库:40+ 预装组件,涵盖常见 UI 需求
  3. 简单打包:一键将整个应用打包成单一 HTML 文件
  4. 设计指南:避免 "AI slop",创建独特、专业的界面

关键命令:

bash
# 初始化
bash scripts/init-artifact.sh <project-name>

# 开发
pnpm dev

# 打包
bash scripts/bundle-artifact.sh

这个 Skill 特别适合需要状态管理、多组件交互或专业 UI 组件的复杂 Web 应用场景。

基于 MIT 许可证发布。内容版权归作者所有。