mcpField
S
solid-js-best-practices

solid-js-best-practices

github.com/richardcarls開発292 回インストール4 週間前に更新
リポジトリ

solid-js-best-practices について

solid-js-best-practicesは、Solid.jsアプリのAI支援による実装、レビュー、リファクタリング向けのルール集です。テーマや作業別に整理され、例を適用する前にプロジェクトのSolid.jsバージョンを確認します。

主な機能

  1. 01バージョンに応じたルール選択
  2. 02リアクティビティとコンポーネントの指針
  3. 03状態、DOM、パフォーマンスのルール
  4. 04アクセシビリティとテストの指針
  5. 05Web Component統合ルール

活用シーン

  1. 01Solid.jsコンポーネントの作成
  2. 02Solid.jsコードのレビュー
  3. 03アプリ状態とリアクティビティのリファクタリング
  4. 04Solid.jsへのカスタム要素の統合

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/richardcarls/solid-js-best-practices --skill solid-js-best-practices

インストール後、Claude Code で/solid-js-best-practicesを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

LICENSE
.gitignore
AGENTS.md
README.md
CHANGELOG.md
docs/
version-support-plan.md
rules/
1-1-use-signals-correctly.md
1-4-avoid-signal-in-effect.md
1-2-use-memo-for-derived.md
1-3-effects-for-side-effects.md
1-6-batch-signal-updates.md
2-2-use-merge-props.md
1-5-use-untrack-when-needed.md
2-1-never-destructure-props.md
1-7-no-primitives-in-reactive-contexts.md
2-10-custom-element-typescript-declarations.md
2-3-use-split-props.md
2-5-component-composition.md
2-4-use-children-helper.md
2-6-components-return-once.md
3-1-use-show-for-conditionals.md
2-8-style-prop-conventions.md
2-9-never-call-components-as-functions.md
2-7-no-react-specific-props.md
3-3-use-index-for-primitives.md
3-6-stable-component-mount.md
3-5-provide-fallbacks.md
3-7-use-keyed-for-stateful-children.md
3-2-use-for-for-lists.md
3-4-use-switch-match.md

詳細

Solid.js のベストプラクティス

AI 支援によるコード生成、レビュー、リファクタリングに最適化された、Solid.js アプリケーションとコンポーネント構築のための包括的なベストプラクティスです。

バージョンに応じたルール

コード例を適用する前に、プロジェクトのマニフェストとロックファイルで solid-js のバージョンを確認してください。メジャーバージョンが不明な場合は、プロジェクトで使用しているメジャーバージョンを確認してください。既存のルールファイルは Solid 1.x に基づいています。version_basis にはルールの基になったバージョンが記録されていますが、その原則をそのメジャーバージョンに限定するものではありません。現在の対応する API を確認せずに、1.x の API 例を 2.x のプロジェクトにコピーしないでください。Solid 2.x への対応は、公式リリースまで保留されています。プレリリース版の 2.x を使うプロジェクトでは、公式の 1.x 移行ガイドとインストール済みのリリース候補版のドキュメントを参照してください。これらの 1.x 向けルールを、検証済みの 2.x 向けガイダンスとして扱わないでください。

カテゴリ別のルール

1. リアクティビティ(7 ルール)
#ルール優先度説明
1-1シグナルを正しく使う最重要シグナルは count ではなく、必ず関数として count() のように呼び出します
1-2派生値にはメモを使う高計算値には createEffect ではなく createMemo を使います
1-3エフェクトは副作用にのみ使う高派生処理には使わず、副作用にのみ createEffect を使います
1-7リアクティブなコンテキスト内でプリミティブを使わない高エフェクトやメモの内部でフックを呼び出したり、リアクティブプリミティブを作成したりしないでください
1-4エフェクト内でのシグナル設定を避ける中エフェクト内でシグナルを設定すると、無限ループが発生する可能性があります
1-5必要に応じて Untrack を使う中意図しないリアクティブな購読を防ぐには untrack() を使います
1-6シグナルの更新をまとめる低複数の同期的なシグナル更新には batch() を使います
2. コンポーネント(10 ルール)
#ルール優先度説明
2-1props を分割代入しない最重要props を分割代入するとリアクティビティが失われます
2-6コンポーネントは一度だけ return する最重要早期 return は使わず、JSX 内で <Show> や <Switch> などを使います
2-9コンポーネントを関数として呼び出さない最重要必ず JSX または createComponent() を使います。直接呼び出すとリアクティブスコープが漏れます
2-2mergeProps を使う高props のデフォルト値には mergeProps を使います
2-3splitProps を使う高props のグループを安全に分けるには splitProps を使います
2-7React 固有の props を使わない高className ではなく class を、htmlFor ではなく for を使います
2-10カスタム要素の TypeScript 宣言高JSX 名前空間でカスタム要素のタグを宣言し、新しい属性については DOM 型を拡張します
2-4children ヘルパーを使う中children に安全にアクセスするには children() ヘルパーを使います
2-5コンポジションを優先する中props のバケツリレーより、コンポジションとコンテキストを優先します
2-8style prop の規約中style にはケバブケースのプロパティを使ったオブジェクト構文を使用します
3. 制御フロー(7 ルール)
#ルール優先度説明
3-1条件分岐には Show を使用するHIGH条件付きレンダリングには <Show> を使用し、呼び出し元で絞り込まれた値が必要な場合は関数の子を使用します
3-2リストには For を使用するHIGH参照キーに基づくリストのレンダリングには <For> を使用します
3-7状態を持つ子には keyed を使用するHIGH子が内部状態を持ち、真偽値だけでなく値の同一性が重要な場合は、keyed を追加します
3-3プリミティブには Index を使用するMEDIUM同一性より配列のインデックスが重要な場合は、<Index> を使用します
3-4Switch/Match を使用するMEDIUM複数の条件には <Switch>/<Match> を使用します。絞り込まれたアクセサーは、対応する分岐が無効になると例外をスローします
3-6コンポーネントのマウントを安定させるMEDIUM同じコンポーネントを複数の Switch/Show 分岐でレンダリングすることは避けます
3-5フォールバックを指定するLOWローディング状態には、必ず fallback プロパティを指定します
4. 状態管理(7 ルール)
#ルール優先度説明
4-1Signals と StoresHIGHプリミティブにはシグナルを、ネストされたオブジェクトにはストアを使用します
4-2Store のパス構文を使用するHIGH細かく効率的なストアの更新にはパス構文を使用します
4-3ミューテーションには produce を使用するMEDIUM複雑な、ミュータブルな形式のストア更新には produce を使用します
4-4サーバーデータには reconcile を使用するMEDIUMサーバーまたは外部のデータを統合する場合は reconcile を使用します
4-5グローバル状態には Context を使用するMEDIUMコンポーネント間で共有する状態には Context API を使用します
4-6ラッパーを使って関数をストアに保存するHIGHsetStore が関数値をアップデーター関数として呼び出さないよう、関数値をラップします
4-7ページの所有境界でクリーンアップするHIGH複数のルーティングされたペインがマウントされたままの場合は、ページごとにクリーンアップします。共有コンテキストを分割する際は、すべてのコンテキストフィールドを確認します
5. 参照と DOM(10 ルール)
#ルール優先度説明
5-1参照を正しく使う高条件付き要素にはコールバック参照を使います
5-2onMount で DOM にアクセスする高レンダリング中ではなく、onMount で DOM 要素にアクセスします
5-3onCleanup でクリーンアップする高サブスクリプションとタイマーは必ずクリーンアップします
5-5innerHTML を避ける高XSS を防ぐため innerHTML を避け、JSX または textContent を使います
5-7Web コンポーネントの制御状態高モダンなカスタム要素では prop:* プロパティと on:wc-* イベントを使い、ネイティブまたはレガシー API には参照/エフェクトを使います
5-8シグナルの変更を View Transition でラップする高ブラウザーが新しいリアクティブ状態を適用する前に古い DOM をキャプチャできるよう、startViewTransition() の内側で Solid のセッターを呼び出します
5-9双方向スクロール同期高確定したスクロール位置のみを通知し、自身のエコーによる再スクロールはスキップします
5-10progress/meter の値がない場合への対応高value は常にプロパティであり、undefined ではエラーになるため、attr:value を使います
5-4ディレクティブを使う中再利用可能な要素の動作には use: ディレクティブを使います
5-6イベントハンドラーのパターン中on:/oncapture: 名前空間と配列ハンドラー構文を正しく使います
6. パフォーマンス(6 ルール)
#ルール優先度説明
6-1不要なトラッキングを避ける高リアクティブコンテキストの外でシグナルにアクセスしないでください
6-2遅延コンポーネントを使う中大きなコンポーネントのコード分割には lazy() を使います
6-3Suspense を使う中非同期読み込みの境界には <Suspense> を使います
6-6Web コンポーネントの CSS とバンドル戦略中コンポーネントを個別にインポートし、::part() のオーバーライドはグローバルスタイルシートに配置します
6-4ストアへのアクセスを最適化する低必要なストアのプロパティのみを参照します
6-5classList を優先する低条件付きのクラス切り替えには classList プロパティを使います
7. アクセシビリティ(4 ルール)
#ルール優先度説明
7-1セマンティック HTML を使う高適切なセマンティック HTML 要素を使います
7-2ARIA 属性を使う中カスタムコントロールには適切な ARIA 属性を適用します
7-3キーボード操作に対応する中すべてのインタラクティブ要素をキーボードで操作できるようにします
7-4ルータールートリンクに end マッチを設定する高ルートリンクがすべてのルートで現在のリンクとして扱われないよう、end マッチを追加します
8. テスト(12 件のルール)
#ルール優先度説明
8-1Solid 用に Vitest を設定するCRITICALSolid 固有の解決条件とプラグインを使って Vitest を設定します
8-2render をアロー関数でラップするCRITICAL常に render(() => <C />) を使用し、render(<C />) は使用しません
8-3ルート内でプリミティブをテストするHIGHシグナル/エフェクト/メモのテストを createRoot または renderHook でラップします
8-4テストで非同期処理を扱うHIGH非同期の動作には findBy クエリと適切なタイマー設定を使用します
8-5アクセシブルなクエリを使用するMEDIUMテスト ID よりもロールやラベルによるクエリを優先します
8-6ロジックのテストと UI のテストを分離するMEDIUMプリミティブ/フックは、コンポーネントのレンダリングとは独立してテストします
8-7ブラウザー依存の動作にはブラウザーモードを使用するHIGHjsdom では忠実に再現できないレイアウト、フォーカス、ネイティブ API、カスタム要素の動作には、実際のブラウザーを使用します
8-8標準的でない ARIA を使うヘッドレス UI ライブラリのテストMEDIUMヘッドレス UI ライブラリは分かりにくい ARIA 構造やポータルを使用するため、クエリを実行する前に実際のツリーを確認します
8-9ブラウザーのネイティブ API テストを分離するHIGHテスト間で IndexedDB と localStorage をクリアし、deleteDatabase の前に接続を閉じます
8-10ルーターの統合テストHIGHMemoryRouter の root プロパティを使って、レイアウトプロバイダーにルーターコンテキストを提供します
8-11TanStack Query のテストを設定するHIGHテストごとに新しい QueryClient を作成し、リトライとキャッシュを無効にします
8-12Structured Clone の前にプロキシを解除するHIGHIndexedDB にデータを書き込む前に、すべてのリアクティブプロキシを取り除きます
9. Web コンポーネントの統合(8 件のルール)
#ルール優先度説明
9-1アプリのエントリーポイントでカスタム要素を登録するHIGHSolidJS のリアクティブコンテキストが始まる前に /define の副作用をインポートします
9-2スロットの割り当て後に slotchange を処理するHIGHslotchange はマイクロタスクで配信されます。後続のライフサイクルまたはレンダリングフェーズが必要な処理だけを遅延させます
9-3カスタム要素と SolidJS のリアクティビティを切り離すMEDIUM一方向のデータフロー(SolidJS -> 属性/プロパティ -> イベント -> SolidJS)を使用し、SolidJS のリアクティブコンテキストからカスタム要素の内部状態を読み取らないでください
9-4Web コンポーネントのラッパーを薄く保つHIGHラッパーはラベル、レイアウト、型の変換、フォームとの連携を担当し、カスタム要素はタイミングとネイティブ同期を担当します
9-5プロパティと属性のバインディングHIGHカスタム要素の動的な props はすでにプロパティです。意図を明示するには prop:* を、data-*、ID 参照 ARIA、CSS から見える属性には attr:* を使用します
9-6カスタムフィールドをフォームライブラリに登録するHIGHプロパティバインドされたカスタムフィールドが、遅延読み込みされるフォームライブラリのレジストリに登録されるようにします
9-7Web コンポーネントを多用するフォームの状態を Store に保持するMEDIUMカスタム要素がすでにフィールド操作を担っている場合は、Solid の Store を優先します
9-8controlled のみの WC にラッパーシグナルを使用するHIGHWC に defaultValue がない場合は、ラッパーで createSignal を使い、非制御から制御への橋渡しを担います

タスクベースのルール選択

新しいコンポーネントの作成

Solid.js コンポーネントを新しく作成する際は、以下のルールを読み込んでください。

ルール理由
1-1シグナルを関数として呼び出すようにします
2-1リアクティビティの破損を防ぎます
2-6早期リターンを避け、JSX 内で制御フローを使用します
2-9コンポーネントを通常の関数として呼び出しません
2-2デフォルトの props を正しく処理します
2-3ローカルの props と転送する props を分けます
3-1条件付きレンダリングを適切に行います
3-7フォームや状態を持つ子には keyed を使用します
3-2リストを効率的にレンダリングします
5-3メモリーリークを防ぎます
Web コンポーネントの統合

Lit やその他のカスタム要素を SolidJS と統合する際は、以下のルールを読み込んでください。

ルール理由
9-1SolidJS のコンテキストがマウントされる前に登録します
9-2ブラウザーが slotchange を通知した後に割り当て済みノードを処理します
9-3一方向のデータフローを設計します
9-4ラッパーはアプリケーションの関心事に絞ります
9-5プロパティには prop:*、CSS や ARIA が参照する属性には attr:* を使用します
9-6プロパティにバインドされたフィールドをフォームライブラリのレジストリーに登録します
9-7カスタム要素を多用するフォームの状態をストアに保持します
5-6カスタム要素のイベントには on: 名前空間を使用します
コードレビュー

コードレビューでは、以下のルールを重点的に確認してください。

優先度ルール
重大1-1, 2-1, 2-6, 2-9
高1-2, 1-3, 1-7, 2-7, 5-2, 5-3, 5-5
パフォーマンスの最適化

パフォーマンスを最適化する際は、以下のルールを読み込んでください。

ルール焦点
1-2不要な再計算を防ぎます
1-6更新サイクルを減らします
4-2ストアを細かく更新します
6-1不要なサブスクリプションを防ぎます
6-2コード分割
6-4ストアへのアクセスを効率化します
状態管理

アプリケーションの状態を扱う際は、以下のルールを読み込んでください。

ルール焦点
4-1適切なプリミティブを選択します
4-2効率的な更新
4-3複雑な変更
4-4外部データの統合
4-5コンポーネント間の状態
4-6ストア内の関数値
4-7コンテキストを共有する複数のマウント済みペイン
アクセシビリティ監査

アクセシビリティを監査する際は、以下のルールを読み込んでください。

ルール焦点
7-1セマンティックな構造
7-2スクリーンリーダーのサポート
7-3キーボードユーザー
7-4ルーターリンクの現在のページ状態
テストの作成

テストを作成またはレビューする際は、以下のルールを読み込んでください。

ルール焦点
8-1正しい Vitest 設定
8-2リアクティブなレンダリングスコープ
8-3プリミティブのリアクティブな所有権
8-4非同期クエリとタイマー
8-5アクセシブルなクエリの選択
8-6テストアーキテクチャ
8-7ブラウザモードと jsdom の使い分け
8-8ポータルと標準的でない ARIA 構造
8-9IDB と localStorage のクリーンアップパターン
8-10統合テスト用の MemoryRouter セットアップ
8-11テスト用の QueryClient 設定
8-12IndexedDB に書き込まれるストアプロキシ
Web コンポーネント/カスタム要素の統合

カスタム要素ライブラリ(Shoelace、FAST、Lion、Material Web Components など)や、<dialog>、Popover API などのネイティブブラウザー API を使用する際は、以下のルールを読み込んでください。

ルール理由
2-10JSX 名前空間でカスタム要素のタグを宣言し、新しい HTML 属性や実験的な CSS プロパティに型を付けます
5-6すべてのカスタム要素イベントに on: を使用し、CustomEvent のペイロードに正しく型を付けます
5-7宣言的な prop:*/on:wc-* を優先し、ネイティブまたはレガシー API に限り ref を使用します
6-6ツリーシェイキングのためにコンポーネントごとにインポートし、::part() のオーバーライドはグローバル CSS のみに記述します
9-8WC に defaultValue がない場合は、createSignal で非制御から制御への橋渡しを管理します
5-8Solid の DOM 更新を View Transition のスナップショットコールバック内に保ちます
5-10ネイティブの <progress>/<meter> で value が undefined の場合、例外が発生します
カルーセルとスクロール同期コンポーネント

インデックスがスクロールコンテナーに反映され、そこから再び通知される場合は、5-9 を読み込んでください。

React からの移行

シグナル、 コンポーネントの実行、 リアクティブな props、 HTML の prop 名、 スタイル構文、 制御フロー、 リストのレンダリング、および イベントハンドラーを読み込んでください。

ツール

これらのベストプラクティスに加えて自動リンティングを行うには、 eslint-plugin-solid を使用してください。このプラグインは、このスキルで扱う問題(分割代入された props、早期リターン、React 固有の props、innerHTML の使用、style prop の形式など)の多くを検出し、自動修正可能なルールも提供します。

リソース

コメント