bulletproof-react-patterns について
bulletproof-react-patterns は、bulletproof-react を基にした React 開発者向けのアーキテクチャガイドです。プロジェクト構成からテスト、セキュリティ、パフォーマンスまで扱います。
主な機能
- 01機能単位のプロジェクト構成
- 02コンポーネントと API 層の定義
- 03クライアント状態とサーバー状態の分離
- 04エラー処理とテスト戦略の設計
- 05セキュリティと性能の実践
活用シーン
- 01大規模 React アプリの構成設計
- 02API・状態・エラー処理のパターン策定
- 03コンポーネント・統合・E2E テストの計画
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ grahamcrackers/ skills --skill bulletproof-react-patternsインストール後、Claude Code で/bulletproof-react-patternsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/api-layer.mdcomponents-and-styling.mderror-handling.mdperformance.mdproject-standards.mdproject-structure.mdREADME.mdsecurity.mdstate-management.mdtesting.md詳細
Bulletproof React のパターン
スケーラブルで保守しやすい React アプリケーションを構築するためのアーキテクチャパターンです。bulletproof-react をベースにしています。
主な参考資料
| トピック | 説明 | 参考資料 |
|---|---|---|
| プロジェクト構成 | 機能ベースの構成、一方向アーキテクチャ、ESLint による徹底 | project-structure |
| コンポーネントとスタイル設定 | コンポーネント階層、サードパーティライブラリのラップ、ヘッドレスライブラリとスタイル付きライブラリ | components-and-styling |
| API レイヤー | API クライアント、リクエスト宣言、クエリー/ミューテーションフックのパターン | api-layer |
| 状態管理 | コンポーネント、アプリケーション、サーバーキャッシュ、フォーム、URL の状態分類 | state-management |
| エラー処理 | エラーバウンダリー、API エラー、Sentry によるエラートラッキング | error-handling |
| テスト | Vitest、Testing Library、Playwright、MSW による単体、統合、E2E テスト戦略 | testing |
| プロジェクト標準 | ESLint、Prettier、TypeScript、Husky、絶対インポート、ファイル命名 | project-standards |
| セキュリティ | 認証、トークン保存、XSS 防止、RBAC/PBAC 認可 | security |
| パフォーマンス | コード分割、データの事前取得、状態の最適化、children パターン | performance |
プロジェクト構成
ファイルの種類ではなく、機能ごとに構成します。
src/
├── app/ # Application shell (routes, providers, router)
├── assets/ # Static files (images, fonts)
├── components/ # Shared, reusable UI components
├── config/ # Environment variables, constants
├── features/ # Feature-based modules
├── hooks/ # Shared custom hooks
├── lib/ # Pre-configured library wrappers
├── stores/ # Global client state
├── testing/ # Test utilities, MSW handlers, factories
├── types/ # Shared TypeScript types
└── utils/ # Pure utility functions
機能モジュール
features/users/
├── api/ # API functions and query hooks
├── components/ # Feature-specific components
├── hooks/ # Feature-specific hooks
├── types/ # Feature-specific types
└── utils/ # Feature-specific utilities
ルール:
- 機能間で相互にインポートしないでください。アプリのレベルで組み合わせます。
- コードは一方向に流れます:shared → features → app。
- 2 つ以上の機能で再利用される場合にのみ、shared ディレクトリに移します。
- Vite のツリーシェイキングのため、バレルによる再エクスポートより直接インポートを優先します。
コンポーネント階層
Page Components → route-level, compose features, handle layout
└── Feature Components → feature-specific, business logic
└── UI Components → shared primitives, no business logic
API レイヤーパターン
// Pure API function
function getUsers(params?: GetUsersParams): Promise<UsersResponse> {
return api.get("/users", { params });
}
// Query hook wrapping the API function
function useUsers(params?: GetUsersParams) {
return useQuery({
queryKey: ["users", params],
queryFn: () => getUsers(params),
});
}
状態管理の境界
| 状態の種類 | 解決策 | 例 |
|---|---|---|
| サーバー状態 | TanStack Query | ユーザーデータ、投稿、API レスポンス |
| クライアント状態(グローバル) | Zustand / Jotai | テーマ、サイドバーの開閉、ユーザー設定 |
| クライアント状態(ローカル) | useState / useReducer | フォーム入力、切り替え、モーダルの開閉 |
| URL 状態 | URL search params / router | フィルター、ページネーション、アクティブなタブ |
| フォーム状態 | React Hook Form | 複数ステップのフォーム、バリデーション |
サーバー状態とクライアント状態を混在させないでください。 クエリデータを useState にコピーしないでください。
エラー階層
App Error Boundary → catches unrecoverable crashes
└── Route Error Boundary → catches route-level failures, shows retry
└── Feature Error Boundary → catches feature-specific errors
テスト戦略
| レイヤー | ツール | テスト対象 |
|---|---|---|
| コンポーネント | Testing Library | レンダリング結果、ユーザー操作、アクセシビリティ |
| フック | renderHook | 状態の変化、副作用 |
| API | MSW | リクエストとレスポンスの処理、エラー状態 |
| 統合 | Testing Library + MSW | 機能全体のフロー(レンダリング → 操作 → 検証) |
| E2E | Playwright | 重要なユーザージャーニー |
規約
| 項目 | 規約 | 例 |
|---|---|---|
| コンポーネント | PascalCase | UserCard.tsx |
| フック | camelCase、use 接頭辞 | useUsers.ts |
| ユーティリティ | camelCase | formatDate.ts |
| 型 | PascalCase | User、CreateUserInput |
| 定数 | UPPER_SNAKE_CASE | MAX_RETRIES |
| ディレクトリ | kebab-case | user-settings/ |
| ファイル | kebab-case | user-card.tsx |
インポート
相対パスが深くなるのを避けるため、パスエイリアスを使用します。
import { Button } from "@/components/ui/button";
import { useUsers } from "@/features/users/api";
tsconfig.json で @/ を src/ のエイリアスとして設定します。
コメント
Markdown 対応