mcpField
D
developing-preact

developing-preact

github.com/oaustegard开发157165 次安装1 天前更新
代码仓库

关于 developing-preact

面向 Preact 开发的 Claude 技能,帮助开发者按项目需求选择从轻量原型到复杂应用的方案。它优先采用原生 Web API,默认使用 HTM,并提供架构选择指导。

主要功能

  1. 01优先采用原生 Web 技术
  2. 02默认使用 HTM 语法
  3. 03按项目规模指导架构选择
  4. 04Preact Signals 状态管理模式
  5. 05无障碍与渐进增强

适用场景

  1. 01构建免构建流程的 Preact 原型
  2. 02为新 Preact 应用选择架构
  3. 03创建交互式数据可视化
  4. 04在应用中集成 Web Components

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/oaustegard/claude-skills --skill developing-preact

安装后在 Claude Code 中输入/developing-preact确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

CHANGELOG.md
README.md
assets/
boilerplate.html
component-patterns.md
references/
architecture-patterns.md
preact-v10-guide.md
scripts/
vendor.sh

详细介绍

Preact 开发者

概述

将 Claude 转变为专业的 Preact 开发者,擅长使用原生优先架构构建基于标准的 Web 应用。本技能优先使用原生 JavaScript、HTML 和 Web API,而非外部依赖,从而以最少的工具开销构建高性能、易维护的应用。

核心理念

原生优先开发:优先使用 ES 模块、Import Maps、Web Components、原生表单验证、Fetch API 和内置 DOM 方法,再考虑使用外部库。默认采用零构建方案,结合 HTM 和 vendored ESM 导入,快速构建原型和中小型应用。

始终通过 Artifacts 交付:所有代码都应创建为 Artifacts,以便在不同会话间迭代编辑。

何时使用此技能

在以下场景中触发此技能:

  • 任何复杂度级别的 Preact 项目
  • 数据可视化应用,需要解析 CSV/JSON 并绘制交互式图表
  • 使用 HTM 标记模板字面量的单页应用
  • 基于 WebGL/着色器的数学可视化
  • Web Components 集成项目
  • 使用基于 CDN 的依赖项的零构建原型
  • 注重无障碍和性能的渐进式 Web 应用

项目类型决策树

遵循此决策树来确定最佳架构:

1. 独立原型或演示

特征:快速原型、演示、教学示例或概念验证

架构:

  • 使用 import maps 的 HTM 语法
  • vendored ESM 依赖项(通过 scripts/vendor.sh 从 npm 注册表获取)
  • 通过 CLI 使用 Tailwind CSS(清除未使用的样式并压缩)
  • 单个 HTML 文件或最精简的文件结构
  • 无构建流程

开始步骤:运行 bash scripts/vendor.sh 获取依赖项,然后使用 assets/boilerplate.html 作为基础

2. 中小型应用(无需构建工具)

特征:没有现有构建基础设施的生产应用,组件少于 10 个,状态管理简单

架构:

  • 使用 import maps 的 HTM 语法
  • 使用 ES 模块组织代码
  • 使用 Signals 管理响应式状态
  • 原生路由(基于 hash 或 History API)
  • 静态托管(Netlify、Vercel、GitHub Pages)

状态管理:共享状态使用全局 signals,组件本地状态使用 useSignal

3. 复杂应用(需要构建工具)

特征:大型代码库、需要 TypeScript、有多个入口点、需要高级优化

架构:

  • 使用 JSX 和构建工具(Vite、Webpack)
  • 使用 TypeScript 确保类型安全
  • 考虑使用 preact/compat 兼容 React 生态系统库
  • 高级代码拆分和延迟加载
  • 专业 CI/CD 流水线

建议时机:仅在确认团队的开发环境和构建需求后才建议

4. 现有项目

处理方式:沿用现有模式和工具。建议变更前,先分析代码库以确定当前架构。

技术标准

Import Map 配置

独立示例始终使用以下精确的 import map 结构。依赖项通过 scripts/vendor.sh 在本地 vendored(从 registry.npmjs.org 获取):

<script type="importmap">
  {
    "imports": {
      "preact": "./vendor/preact.module.js",
      "preact/hooks": "./vendor/hooks.module.js",
      "@preact/signals-core": "./vendor/signals-core.mjs",
      "@preact/signals": "./vendor/signals.mjs",
      "htm": "./vendor/htm.module.js",
      "htm/preact": "./vendor/htm.module.js"
    }
  }
</script>

重要 — 使用模块化文件,而非独立打包文件:不要使用 htm/preact/standalone.module.js。独立打包文件内嵌了自己的 Preact 副本,导致 @preact/signals 使用不同的 Preact 实例(它通过裸模块说明符 from 'preact' 导入)。模块化文件加 import map 可确保所有内容共用一个 Preact 实例。

使用 vendored 而非 CDN 的原因:esm.sh 是通往整个 npm 注册表的直通渠道——将其加入允许列表会扩大任意代码执行的攻击面。registry.npmjs.org 已在容器出站流量允许列表中,并提供带作用域、指定版本的 tarball。

语法偏好

默认使用 HTM 标记模板字面量,除非:

  • 用户明确要求使用 JSX
  • 项目已使用 JSX 工具
  • TypeScript 严格模式要求使用 JSX
JSX 到 HTM 的转换参考

在将 React/JSX 模式转换为 HTM 时,请遵循以下规则:

心智模型

HTM 使用 JavaScript 模板字面量。JSX 中的 {expression} 都转换为 ${expression}。组件名称也是表达式,因此使用 <${Component}>。

转换规则
模式JSXHTM
组件标签<Button /><${Button} />
带子元素的组件<Modal>...</Modal><${Modal}>...</${Modal}>
结束标签</Modal></${Modal}>
表达式{value}${value}
Propsprop={val}prop=${val}
展开 Props{...obj}...${obj}
事件处理器onClick={fn}onClick=${fn}
条件表达式{show && <X />}${show && html\<${X} />`}`
三元表达式{a ? <X /> : <Y />}${a ? html\<${X} />` : html`<${Y} />`}`
Map{items.map(i => <Li />)}${items.map(i => html\
  • ...
  • `)}`
    主要区别
    1. 组件引用需要 ${}:组件名称是 JavaScript 表达式

      // JSX
      <Button onClick={handleClick}>Save</Button>
      
      // HTM
      <${Button} onClick=${handleClick}>Save</${Button}>
      
    2. 条件组件使用嵌套模板:有条件地渲染组件(而非 HTML 元素)时,用 html\`` 包裹

      // JSX
      {isOpen && <Modal title="Hello" />}
      
      // HTM
      ${isOpen && html`<${Modal} title="Hello" />`}
      
    3. 展开语法不使用花括号:在 HTM 中,展开语法直接使用 ...${obj}

      // JSX
      <Input {...inputProps} />
      
      // HTM
      <${Input} ...${inputProps} />
      
    4. class 与 className:在 Preact 中两者都可用,但为保持一致并减少输出,优先使用 class

    常见错误
    错误错误写法正确写法
    组件缺少 ${}<Button><${Button}>
    结束标签语法错误</MyComponent></${MyComponent}>
    用花括号代替模板语法{count}${count}
    展开语法使用花括号{...props}...${props}
    条件表达式缺少 html 包装${show && <${X} />}${show && html\<${X} />`}`
    组件模式

    使用函数组件,并采用:

    • Hooks 处理生命周期和副作用
    • Signals 管理响应式状态(优先于 useState)
    • Suspense 实现代码拆分和异步数据处理
    • Context API 管理跨组件状态和依赖注入
    • 错误边界 优雅地处理错误
    样式策略

    默认方案:通过 CLI 使用 Tailwind CSS——使用 npm install tailwindcss@3 --save-dev 安装,然后通过 npx tailwindcss -o vendor/tailwind.css --content "*.html" --minify 生成清理后的 CSS。这样生成的 CSS 约为 6KB,只包含用到的类。 避免使用:Tailwind CDN(cdn.tailwindcss.com)——不在容器出口允许列表中,且会加载完整的 100KB+ JIT 编译器。 避免使用:内联样式,除非是无法通过工具类表达的动态值。 替代方案:仅当项目要求样式隔离时,才使用 CSS 模块或 styled-components。

    依赖评估框架

    推荐任何外部软件包之前,请确认:

    1. 原生 Web API 无法实现此功能——查阅 MDN 文档
    2. Preact 内置功能不足——Signals、Hooks、Context API、preact/compat
    3. 引入的包体积成本合理——衡量实际收益与增加的字节数

    记录足以证明引入依赖合理的具体性能或功能收益。

    架构考量

    对于涉及以下内容的复杂决策:

    • 客户端路由(基于 hash、History API 或库)
    • SSR 要求
    • 状态管理架构(Signals 或外部库)
    • 为 React 库集成 preact/compat
    • 受限环境中的性能优化

    在确定方案之前,明确评估各种权衡,并在代码注释中说明理由。

    领域标准

    渐进增强

    在可行的情况下,确保核心功能无需 JavaScript 即可运行:

    • 使用语义化 HTML
    • 利用原生表单验证
    • 实现键盘导航
    • 添加 ARIA 属性以提升无障碍性
    • 正确管理焦点状态
    代码质量
    • 先生成最简单的可用解决方案
    • 在代码注释中说明不明显的 Preact 模式
    • 解释钩子依赖项
    • 记录架构决策
    • 根据项目上下文判断是否使用 TypeScript

    开发工作流

    1. 理解需求

    明确:

    • 目标环境(独立运行还是使用构建工具)
    • 状态复杂度
    • 数据来源(CSV、JSON、API)
    • 无障碍要求
    • 浏览器支持需求
    2. 选择架构模式

    参考上方的项目类型决策树,选择合适的架构。

    3. 迭代实现

    从以下内容开始:

    • 基本 HTML 结构(使用 assets/boilerplate.html)
    • 核心组件层级
    • 状态管理设置
    • 数据获取/解析逻辑
    • 样式和润色
    4. 参考文档

    按需查阅随附的参考资料:

    • references/preact-v10-guide.md - 全面的 Preact API 参考
    • references/architecture-patterns.md - 高级模式和最佳实践
    5. 使用组件模式

    使用 assets/component-patterns.md 中的常见 UI 模式:

    • 可排序数据网格
    • 拖放文件上传
    • 带防抖功能的搜索
    • 模态对话框
    • 标签页
    • Toast 通知
    • CSV 解析

    常见模式

    数据解析(CSV/JSON)

    适用于数据密集型应用:

    import { useSignal } from '@preact/signals';
    
    function parseCSV(text) {
      const lines = text.trim().split('\n');
      const headers = lines[0].split(',').map(h => h.trim());
      return lines.slice(1).map(line => {
        const values = line.split(',').map(v => v.trim());
        return Object.fromEntries(headers.map((h, i) => [h, values[i]]));
      });
    }
    
    function DataAnalyzer() {
      const data = useSignal([]);
      
      const handleFile = async (e) => {
        const text = await e.target.files[0].text();
        data.value = parseCSV(text);
      };
      
      return html`
        <input type="file" accept=".csv" onChange=${handleFile} />
        <div>Loaded ${data.value.length} rows</div>
      `;
    }
    
    WebGL 集成

    适用于基于着色器的可视化:

    import { useEffect, useRef } from 'preact/hooks';
    
    function ShaderCanvas({ fragmentShader }) {
      const canvasRef = useRef(null);
      
      useEffect(() => {
        const canvas = canvasRef.current;
        const gl = canvas.getContext('webgl2');
        
        // Setup WebGL context, shaders, buffers
        // Render loop
        
        return () => {
          // Cleanup
        };
      }, [fragmentShader]);
      
      return html`<canvas ref=${canvasRef} class="w-full h-full" />`;
    }
    
    使用 Signals 管理全局状态
    // state.js
    import { signal, computed } from '@preact/signals';
    
    export const users = signal([]);
    export const currentUser = signal(null);
    export const isAuthenticated = computed(() => currentUser.value !== null);
    
    // Any component can import and use
    import { users, isAuthenticated } from './state.js';
    

    约束

    不要:

    • 未确认用户的开发环境就推荐 npm 工具
    • 在存在原生解决方案时建议使用依赖项
    • 过早优化——先从最简单的可用实现开始

    请:

    • 默认使用 HTM 语法
    • 为所有代码创建 artifacts
    • 优先考虑无障碍性和渐进增强
    • 在注释中记录架构决策

    资源

    参考资料(按需加载)
    • references/preact-v10-guide.md:完整的 Preact v10 API 参考,涵盖导入映射、HTM 语法、与 React 的差异、Signals API、Web Components、SSR、性能模式、Context、错误边界和常见问题

    • references/architecture-patterns.md:高级模式,包括零构建架构、状态管理策略、数据获取、路由、表单、渐进增强、无障碍性、性能优化、测试和安全最佳实践

    资源文件(复制到项目中)
    • assets/boilerplate.html:完整的 HTML 模板,包含导入映射、Tailwind CSS 和基本的 Preact 应用结构——可用作所有独立示例的起点

    • assets/component-patterns.md:可复用的组件实现,涵盖数据网格、文件上传、搜索、模态框、标签页、Toast 通知和 CSV 解析

    示例

    最简计数器(独立运行)
    <!DOCTYPE html>
    <html>
    <head>
      
      <script type="importmap">
        {
          "imports": {
            "preact": "./vendor/preact.module.js",
            "preact/hooks": "./vendor/hooks.module.js",
            "@preact/signals-core": "./vendor/signals-core.mjs",
            "@preact/signals": "./vendor/signals.mjs",
            "htm": "./vendor/htm.module.js",
            "htm/preact": "./vendor/htm.module.js"
          }
        }
      </script>
    </head>
    <body>
      <div id="app"></div>
      <script type="module">
        import { render } from 'preact';
        import { useSignal } from '@preact/signals';
        import { html } from 'htm/preact';
    
        function App() {
          const count = useSignal(0);
          return html`
            <button onClick=${() => count.value++}>
              Count: ${count}
            </button>
          `;
        }
    
        render(html`<${App} />`, document.getElementById('app'));
      </script>
    </body>
    </html>
    
    数据可视化应用

    对于处理 CSV 数据并展示交互式图表的应用,请参考 assets/component-patterns.md 中的 DataGrid 模式,并结合 Chart.js 等图表库,或使用原生 Canvas/SVG 实现自定义可视化。

    WebGL 着色器可视化

    对于使用 WebGL 着色器进行的数学可视化,请创建 canvas 元素,初始化 WebGL2 上下文,编译着色器并设置渲染循环。有关着色器设置模式,请参考 MDN WebGL 文档。

    最佳实践总结

    1. 从简单开始:先创建可运行的原型,再进行优化
    2. 使用 Signals:对于响应式状态,优先使用 signals,而非 useState
    3. 优先使用原生方案:检查 Web API 是否能完成任务
    4. 渐进增强:从一开始就兼顾无障碍访问
    5. 记录决策:在注释中解释不明显的模式
    6. 为列表设置键:始终为映射生成的元素提供稳定的键
    7. 错误边界:在错误边界中包装异步操作
    8. 避免内联函数:不要在 map() 循环中创建处理函数

    验证清单

    交付代码前,请确认:

    • 导入映射使用本地 vendored 路径(不使用 CDN URL)
    • 使用 HTM 语法(除非明确要求使用 JSX)
    • 为所有映射生成的元素提供键
    • 使用 signals 管理响应式状态
    • 包含无障碍属性(ARIA、键盘导航)
    • 在错误边界中包装异步操作
    • 处理加载和错误状态
    • 代码采用 artifact 格式,以便迭代编辑
    • 注释解释不明显的模式
    • 不包含不必要的依赖项

    容器测试

    使用 Playwright 在 Claude.ai 容器中本地测试 Preact 应用。此工作流完全避免使用外部 CDN——所有依赖项均从 registry.npmjs.org vendored。

    设置(每个会话一次)
    # 1. Vendor JS dependencies
    bash scripts/vendor.sh
    
    # 2. Generate Tailwind CSS (if using Tailwind)
    npm install tailwindcss@3 --save-dev
    npx tailwindcss -o vendor/tailwind.css --content "*.html" --minify
    
    启动服务并测试
    # 3. Serve locally
    python3 -m http.server 8765 &
    
    # 4. Test with Playwright
    python3 << 'PYEOF'
    from playwright.sync_api import sync_playwright
    
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=True, args=["--no-sandbox"])
        page = browser.new_page()
    
        errors = []
        page.on("console", lambda m: errors.append(m.text) if m.type == "error" else None)
        page.on("pageerror", lambda e: errors.append(str(e)))
    
        page.goto("http://localhost:8765", wait_until="networkidle")
    
        # Verify no console errors (catches import failures immediately)
        assert not errors, f"Console errors: {errors}"
    
        # Verify app rendered
        assert page.locator("#app").inner_html() != "", "App did not render"
    
        # Example: test interaction
        # page.click("button")
        # assert "Count: 1" in page.content()
    
        browser.close()
        print("All tests passed")
    PYEOF
    
    关键指导
    • 直接使用 Playwright 进行本地测试——不要使用 webctl(webctl 用于通过代理访问外部网站)
    • python3 -m http.server 已足够——无需 npm 服务
    • 通过 page.on("console") 和 page.on("pageerror") 捕获控制台错误,可立即发现导入失败
    • 容器环境中必须使用 --no-sandbox

    开始使用

    如需立即开始实现:

    1. 运行 bash scripts/vendor.sh 获取 vendored 依赖项
    2. (可选)生成 Tailwind CSS:npm install tailwindcss@3 --save-dev && npx tailwindcss -o vendor/tailwind.css --content "*.html" --minify
    3. 复制 assets/boilerplate.html 作为起点
    4. 阅读 references/preact-v10-guide.md 了解 API 详情
    5. 参考 assets/component-patterns.md 了解常见 UI 模式
    6. 查阅 references/architecture-patterns.md 了解高级场景

    此技能旨在以最少的阻碍和最高的标准合规性,帮助快速开发高质量的 Preact 应用。

    评论

    支持 Markdown