developing-preact について
Preact 開発向けの Claude スキルで、軽量なプロトタイプから大規模アプリまで、要件に応じた進め方を支援します。ネイティブ Web API を優先し、HTM を標準とするほか、構成選択の指針を示します。
主な機能
- 01ネイティブ Web 技術の優先
- 02HTM 構文の標準採用
- 03規模に応じた構成の指針
- 04Preact Signals による状態管理
- 05アクセシビリティとプログレッシブエンハンスメント
活用シーン
- 01ビルド不要の Preact プロトタイプ作成
- 02新規 Preact アプリの構成選択
- 03インタラクティブなデータ可視化の作成
- 04アプリへの Web Components の統合
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ oaustegard/ claude-skills --skill developing-preactインストール後、Claude Code で/developing-preactを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
CHANGELOG.mdREADME.mdassets/boilerplate.htmlcomponent-patterns.mdreferences/architecture-patterns.mdpreact-v10-guide.mdscripts/vendor.sh詳細
Preact 開発者
概要
Claude を、ネイティブファーストのアーキテクチャを使って標準準拠の Web アプリケーションを構築する専門知識を持つ、Preact 専門の開発者に変えます。このスキルでは、外部依存関係よりもネイティブ JavaScript、HTML、Web API を優先し、ツールのオーバーヘッドを最小限に抑えながら、高性能で保守しやすいアプリケーションを作成できます。
基本理念
ネイティブファーストの開発:外部ライブラリを導入する前に、ES モジュール、インポートマップ、Web Components、ネイティブのフォーム検証、Fetch API、組み込みの DOM メソッドを活用します。迅速なプロトタイピングや小〜中規模のアプリケーションでは、HTM とベンダー提供の ESM インポートを使ったビルド不要のソリューションを標準とします。
常にアーティファクトで提供する:セッションをまたいで反復編集できるよう、すべてのコードをアーティファクトとして作成します。
このスキルを使う場面
次の作業でこのスキルを使用します。
- 複雑さを問わない Preact プロジェクト
- CSV/JSON の解析とインタラクティブなグラフが必要な データ可視化アプリケーション
- HTM のタグ付きテンプレートリテラルを使用する シングルページアプリケーション
- WebGL/シェーダーベースの 数学的な可視化
- Web Components の統合プロジェクト
- CDN ベースの依存関係を使った ビルド不要のプロトタイプ
- アクセシビリティとパフォーマンスを重視する プログレッシブ Web アプリケーション
プロジェクト種別の判断ツリー
この判断ツリーに従って、最適なアーキテクチャを選択します。
1. スタンドアロンのプロトタイプまたはデモ
特徴:迅速なプロトタイプ、デモ、教育用の例、または概念実証
アーキテクチャ:
- インポートマップを使った HTM 構文
- ベンダー提供の ESM 依存関係(
scripts/vendor.shを使って npm レジストリから取得) - CLI 経由の Tailwind CSS(不要なスタイルを削除し、圧縮)
- 単一の HTML ファイル、または最小限のファイル構成
- ビルドプロセスなし
開始方法:bash scripts/vendor.sh を実行して依存関係を取得し、assets/boilerplate.html を土台として使用します。
2. 小〜中規模のアプリケーション(ビルドツールなし)
特徴:既存のビルド環境がない本番アプリケーション、コンポーネント数が 10 未満、シンプルな状態管理
アーキテクチャ:
- インポートマップを使った HTM 構文
- コード構成には ES モジュールを使用
- リアクティブな状態管理には Signals を使用
- ネイティブのルーティング(ハッシュベースまたは History API)
- 静的ホスティング(Netlify、Vercel、GitHub Pages)
状態管理:共有状態にはグローバル Signals を使用し、コンポーネント内の状態には useSignal を使用します。
3. 複雑なアプリケーション(ビルドツールが必要)
特徴:大規模なコードベース、TypeScript の要件、複数のエントリーポイント、高度な最適化の必要性
アーキテクチャ:
- ビルドツール(Vite、Webpack)を使った JSX
- 型安全性のために TypeScript を使用
- React エコシステムのライブラリには preact/compat を検討
- 高度なコード分割と遅延読み込み
- プロフェッショナルな CI/CD パイプライン
推奨するタイミング:チームの開発環境とビルド要件を確認した後に限ります。
4. 既存のプロジェクト
方針:既存のパターンとツールに合わせます。変更を提案する前にコードベースを分析し、現在のアーキテクチャを把握します。
技術標準
インポートマップの設定
スタンドアロンの例では、常に次のインポートマップ構成を使用します。依存関係は scripts/vendor.sh を使ってローカルにベンダー提供します(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' をインポートします)。モジュールファイルとインポートマップを使えば、すべての処理で Preact のインスタンスを共有できます。
CDN ではなくベンダー提供の依存関係を使う理由:esm.sh は npm レジストリ全体へのパススルーです。これを許可リストに追加すると、任意のコード実行の攻撃対象領域が広がります。registry.npmjs.org はすでにコンテナの送信先許可リストに含まれており、スコープとバージョンが指定された tarball を提供しています。
構文の選択
特に指定がない限り、HTM のタグ付きテンプレートリテラルを使用してください。 ただし、次の場合を除きます。
- ユーザーが JSX を明示的に要求している
- プロジェクトですでに JSX ツールを使用している
- TypeScript の strict モードで JSX が必要である
JSX から HTM への変換リファレンス
React/JSX のパターンを HTM に置き換えるときは、次のルールを適用してください。
基本的な考え方
HTM では JavaScript のテンプレートリテラルを使用します。JSX の {expression} はすべて ${expression} になります。コンポーネント名も式なので、<${Component}> のように記述します。
変換ルール
| パターン | JSX | HTM |
|---|---|---|
| コンポーネントタグ | <Button /> | <${Button} /> |
| 子要素を持つコンポーネント | <Modal>...</Modal> | <${Modal}>...</${Modal}> |
| 閉じタグ | </Modal> | </${Modal}> |
| 式 | {value} | ${value} |
| props | prop={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\ |
主な違い
-
コンポーネント参照には
${}が必要です:コンポーネント名は JavaScript の式です// JSX <Button onClick={handleClick}>Save</Button> // HTM <${Button} onClick=${handleClick}>Save</${Button}> -
条件付きコンポーネントにはネストしたテンプレートを使用します:コンポーネント(HTML 要素ではなく)を条件付きでレンダリングする場合は、
html\`` で囲みます// JSX {isOpen && <Modal title="Hello" />} // HTM ${isOpen && html`<${Modal} title="Hello" />`} -
スプレッドに波括弧は不要です:HTM では、スプレッドに
...${obj}を直接使用します// JSX <Input {...inputProps} /> // HTM <${Input} ...${inputProps} /> -
classとclassName:どちらも Preact で動作しますが、一貫性と出力サイズの小ささを優先してclassを使用してください
よくある間違い
| 間違い | 誤り | 正しい |
|---|---|---|
コンポーネントに ${} がない | <Button> | <${Button}> |
| 閉じタグの構文が誤っている | </MyComponent> | </${MyComponent}> |
| テンプレートの代わりに波括弧を使用 | {count} | ${count} |
| 波括弧を使ったスプレッド | {...props} | ...${props} |
| 条件式に html ラッパーがない | ${show && <${X} />} | ${show && html\<${X} />`}` |
コンポーネントのパターン
次のものを使用する関数コンポーネントを作成してください。
- ライフサイクルと副作用にはフック
- リアクティブな状態にはシグナル(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 の CSS が生成されます。
避ける:Tailwind CDN(cdn.tailwindcss.com)。コンテナの外向き通信許可リストに含まれておらず、100KB を超える JIT コンパイラー全体を読み込むためです。
避ける:ユーティリティで表現できない動的な値を除き、インラインスタイルを使用すること。
代替案:スコープ付きスタイルがプロジェクトで必要な場合に限り、CSS モジュールまたは styled-components を使用します。
依存関係の評価フレームワーク
外部パッケージを推奨する前に、次の点を確認してください。
- ネイティブの Web API では実現できない — MDN のドキュメントを確認します
- Preact の組み込み機能では不十分である — シグナル、フック、Context API、preact/compat を確認します
- バンドルサイズのコストに見合う — 追加されるバイト数に対して、得られる実際のメリットを測定します
依存関係の追加を正当化する、具体的なパフォーマンス上または機能上のメリットを記録してください。
アーキテクチャに関する考慮事項
次のような複雑な判断が必要な場合:
- クライアントサイドルーティング(ハッシュベース、History API、ライブラリのいずれか)
- SSR の要件
- 状態管理アーキテクチャ(シグナルと外部ライブラリのどちらか)
- 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. コンポーネントパターンを使用する
一般的な UI パターンには assets/component-patterns.md を活用します。
- 並べ替え機能付きデータグリッド
- ドラッグ&ドロップ対応ファイルアップロード
- 入力を間引く検索
- モーダルダイアログ
- タブ
- トースト通知
- 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 構文を使用する
- すべてのコードにアーティファクトを作成する
- アクセシビリティとプログレッシブエンハンスメントを優先する
- アーキテクチャ上の判断をコメントに記録する
リソース
リファレンス(必要に応じて読み込む)
-
references/preact-v10-guide.md:インポートマップ、HTM 構文、React との違い、Signals API、Web Components、SSR、パフォーマンスパターン、Context、エラーバウンダリー、よくある落とし穴を網羅した Preact v10 API の完全なリファレンス -
references/architecture-patterns.md:ゼロビルドアーキテクチャ、状態管理戦略、データ取得、ルーティング、フォーム、プログレッシブエンハンスメント、アクセシビリティ、パフォーマンス最適化、テスト、セキュリティのベストプラクティスなど、高度なパターンを収録
アセット(プロジェクトにコピー)
-
assets/boilerplate.html:インポートマップ、Tailwind CSS、基本的な Preact アプリ構造を含む完全な HTML テンプレート。すべての単独動作サンプルの出発点として使用します -
assets/component-patterns.md:データグリッド、ファイルアップロード、検索、モーダル、タブ、トースト通知、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 ドキュメントを参照してください。
ベストプラクティスのまとめ
- シンプルに始める:最適化の前に、動作するプロトタイプを作成します
- シグナルを使う:リアクティブな状態には、useState よりシグナルを優先します
- ネイティブを優先する:Web API でタスクを実行できるか確認します
- 段階的に機能を強化する:最初からアクセシビリティを考慮して構築します
- 判断を文書化する:自明でないパターンについてコメントで説明します
- リストのキー:マッピングされた要素には、必ず安定したキーを指定します
- エラーバウンダリー:非同期処理をエラーバウンダリーで囲みます
- インライン関数を避ける:map() ループ内でハンドラーを作成しないでください
検証チェックリスト
コードを提出する前に、以下を確認します。
- インポートマップでベンダー化されたローカルパスを使用している(CDN URL は使用していない)
- HTM 構文を使用している(JSX が明示的に要求されている場合を除く)
- マッピングされたすべての要素にキーを指定している
- リアクティブな状態にシグナルを使用している
- アクセシビリティ属性を含めている(ARIA、キーボード操作)
- 非同期処理をエラーバウンダリーで囲んでいる
- 読み込み状態とエラー状態に対応している
- コードを反復編集できるアーティファクト形式にしている
- 自明でないパターンについてコメントで説明している
- 不要な依存関係を含めていない
コンテナーでのテスト
Playwright を使用して、Claude.ai のコンテナー内で Preact アプリをローカルテストします。このワークフローでは、すべての依存関係を registry.npmjs.org からベンダー化するため、外部 CDN を一切使用しません。
セットアップ(セッションごとに一度)
# 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が必要です
はじめに
すぐに実装を始めるには、以下の手順に従います。
bash scripts/vendor.shを実行して、ベンダー化された依存関係を取得します- (任意)Tailwind CSS を生成します:
npm install tailwindcss@3 --save-dev && npx tailwindcss -o vendor/tailwind.css --content "*.html" --minify assets/boilerplate.htmlを出発点としてコピーします- API の詳細については
references/preact-v10-guide.mdを読みます - 一般的な UI パターンについては
assets/component-patterns.mdを参照します - 高度なシナリオについては
references/architecture-patterns.mdを確認します
このスキルは、手間を最小限に抑え、標準への準拠を最大限に高めながら、高品質な Preact アプリケーションを迅速に開発できるよう設計されています。