mcpField
S
senior-frontend

senior-frontend

github.com/pixel-process-ug開発386 回インストール33 週間前に更新
リポジトリ

senior-frontend について

本番向けの React と TypeScript のフロントエンド開発を支援する構造化スキルです。コードベースの調査、開発、引き継ぎの 3 段階で、テストやアクセシビリティ、品質確認を扱います。

主な機能

  1. 01調査、開発、引き継ぎの 3 段階
  2. 02アトミックデザインのコンポーネント構成
  3. 03厳格な TypeScript と状態管理の指針
  4. 04ユニット、統合、E2E テスト
  5. 05アクセシビリティとパフォーマンスの確認

活用シーン

  1. 01変更前に既存フロントエンドを調査
  2. 02テストを併設した React コンポーネントの開発
  3. 03フロントエンド機能の状態管理を計画
  4. 04引き継ぎ前にフロントエンド品質を確認

インストール

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

$npx skills add https://github.com/pixel-process-ug/superkit-agents --skill senior-frontend

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

詳細

シニアフロントエンドエンジニア

概要

コンテキストの把握、開発、引き継ぎという3段階の構造化されたワークフローに従って、本番環境で使用できる品質のフロントエンドコードを提供します。このスキルでは、Atomic Design に基づくコンポーネントアーキテクチャ、包括的な状態管理パターン、SSR/SSG/ISR の最適化、Vitest、React Testing Library、Playwright を使用した85%を超えるテストカバレッジの必須要件など、厳格な品質基準を徹底します。

開始時に宣言してください:「本番環境向けの React/TypeScript 開発にシニアフロントエンドスキルを使用しています。」


フェーズ1:コンテキストの把握

目標: コードを書く前に、既存のコードベースを理解します。

実施項目
  1. 既存のコードベースの構造と規約を分析します
  2. 技術スタックのバージョンを特定します(React 18/19、Next.js 14/15、TypeScript のバージョン)
  3. 既存のコンポーネントライブラリとデザインシステムを確認します
  4. すでに使用されている状態管理の方法を確認します
  5. ビルドツールと CI パイプラインを把握します
  6. 既存のテスト基盤とカバレッジを把握します
停止 — 以下を満たすまでフェーズ2に進まないでください:
  • 技術スタックのバージョンを特定している
  • 既存のパターンと規約を文書化している
  • テスト基盤を把握している
  • 状態管理の方法を特定している

フェーズ2:開発

目標: 厳格な TypeScript、Atomic Design、TDD に基づいて実装します。

実施項目
  1. Atomic Design に従ってコンポーネントアーキテクチャを設計します
  2. TypeScript の strict モードで実装します
  3. 実装と並行してテストを作成します(適切な場合は TDD を実施します)
  4. パフォーマンスを最適化します(バンドルサイズ、レンダリング、読み込み)
  5. アクセシビリティ基準への準拠を確保します
コンポーネントアーキテクチャの判断表(Atomic Design)
レベル説明ビジネスロジック例
Atoms(アトム)最小の構成要素なしButton、Input、Icon、Badge
Molecules(モレキュール)アトムで構成最小限FormField、SearchBar、Card
Organisms(オーガニズム)ビジネスロジックを含む複雑な構成要素ありDataTable、NavigationBar、CommentThread
Templates(テンプレート)データを含まないページ構造レイアウトのみDashboardLayout、AuthLayout
Pages(ページ)データと連携したテンプレートデータ取得UsersPage、SettingsPage
アトムの例
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  variant?: 'primary' | 'secondary' | 'ghost' | 'danger';
  size?: 'sm' | 'md' | 'lg';
  isLoading?: boolean;
}

export function Button({ variant = 'primary', size = 'md', isLoading, children, ...props }: ButtonProps) {
  return (
    <button className={cn(buttonVariants({ variant, size }))} disabled={isLoading || props.disabled} {...props}>
      {isLoading ? <Spinner size={size} /> : children}
    </button>
  );
}
状態管理の判断表
状態の種類ソリューション使用する場面
サーバー状態React Query/TanStack QueryAPI データ、キャッシュ、同期
フォーム状態React Hook Form + Zodフォームのバリデーション、送信
グローバル UI 状態Zustandテーマ、サイドバーの開閉、モーダル
ローカル UI 状態useState/useReducerコンポーネント固有の状態
URL 状態nuqs/useSearchParamsフィルター、ページネーション、タブ
複雑なローカル状態useReducer複数の関連する状態遷移
共有コンテキストReact Contextテーマ、ロケール、認証(更新頻度が低い場合)
SSR/SSG/ISR の判断表(Next.js App Router)
パターン使用する場面キャッシュ戦略
静的(SSG)コンテンツがほとんど変更されないビルド時
ISRコンテンツが定期的に変更される再検証間隔
SSRリクエストごとにコンテンツが変更されるキャッシュなし
クライアントユーザー固有、インタラクティブブラウザー
サーバーコンポーネントとクライアントコンポーネントの判断
要件コンポーネントの種類
データを直接取得するサーバー(デフォルト)
イベントハンドラー(onClick、onChange)クライアント('use client')
useState/useReducerクライアント
useEffect/useLayoutEffectクライアント
ブラウザー API(window、localStorage)クライアント
クライアント機能を使用するサードパーティーライブラリクライアント
インタラクティブ性が不要サーバー(デフォルト)
停止 — 以下を満たすまでフェーズ3に進まないでください:
  • コンポーネントが Atomic Design の階層に従っている
  • TypeScript の strict モードが有効で、any 型を使用していない
  • すべてのコンポーネントのテストを作成している
  • アクセシビリティを検証している(axe-core)

フェーズ3:引き継ぎ

目標: 品質ゲートを確認し、レビューに備えます。

アクション
  1. テストカバレッジが85%を超えていることを確認します
  2. lintと型チェックをすべて実行します
  3. 複雑なコンポーネントにJSDoc/TSDocでドキュメントを記述します
  4. UIコンポーネントのStorybookストーリーを作成します
  5. パフォーマンス監査を実施します(Lighthouse、バンドル分析)
パフォーマンスチェックリスト
  • バンドルサイズが200KB未満(gzip圧縮後、初回読み込み時)
  • Largest Contentful Paintが2.5秒未満
  • First Input Delayが100ms未満
  • Cumulative Layout Shiftが0.1未満
  • 画像:適切なサイズと形式でnext/imageを使用
  • フォント:next/fontでdisplay swapを使用
  • レイアウトスラッシングがない(DOMの読み取り/書き込みをまとめる)
  • 100項目を超えるリストには仮想化を適用
カバレッジのしきい値
{
  "coverageThreshold": {
    "global": {
      "branches": 85,
      "functions": 85,
      "lines": 85,
      "statements": 85
    }
  }
}
STOP — 次の項目が完了したら引き継ぎ完了です:
  • テストカバレッジが85%を超えていることを確認済み
  • lintと型チェックがエラーゼロで完了
  • パフォーマンス監査を完了
  • 複雑なコンポーネントのドキュメントを作成済み

テスト要件

単体テスト(Vitest + React Testing Library)
describe('Button', () => {
  it('renders children', () => {
    render(<Button>Click me</Button>);
    expect(screen.getByRole('button', { name: 'Click me' })).toBeInTheDocument();
  });

  it('shows loading state', () => {
    render(<Button isLoading>Click me</Button>);
    expect(screen.getByRole('button')).toBeDisabled();
  });

  it('calls onClick when clicked', async () => {
    const onClick = vi.fn();
    render(<Button onClick={onClick}>Click me</Button>);
    await userEvent.click(screen.getByRole('button'));
    expect(onClick).toHaveBeenCalledOnce();
  });
});
統合テスト
  • コンポーネントの組み合わせ(フォーム送信のフロー)
  • MSW(Mock Service Worker)を使ったデータ取得
  • ルーティングとナビゲーション
  • エラーバウンダリーとフォールバック
E2Eテスト(Playwright)
test('user can complete checkout', async ({ page }) => {
  await page.goto('/products');
  await page.getByRole('button', { name: 'Add to cart' }).first().click();
  await page.getByRole('link', { name: 'Cart' }).click();
  await expect(page.getByText('1 item')).toBeVisible();
  await page.getByRole('button', { name: 'Checkout' }).click();
});

React Queryのパターン

function useUsers(filters: UserFilters) {
  return useQuery({
    queryKey: ['users', filters],
    queryFn: () => fetchUsers(filters),
    staleTime: 5 * 60 * 1000,
    placeholderData: keepPreviousData,
  });
}

function useUpdateUser() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: updateUser,
    onMutate: async (newUser) => {
      await queryClient.cancelQueries({ queryKey: ['users'] });
      const previous = queryClient.getQueryData(['users']);
      queryClient.setQueryData(['users'], (old) =>
        old.map(u => u.id === newUser.id ? { ...u, ...newUser } : u)
      );
      return { previous };
    },
    onError: (err, newUser, context) => {
      queryClient.setQueryData(['users'], context.previous);
    },
    onSettled: () => {
      queryClient.invalidateQueries({ queryKey: ['users'] });
    },
  });
}

メモ化の判断表

手法使用する場合使用しない場合
useMemoコストの高い計算、依存値の参照等価性単純な計算、プリミティブ値
useCallbackメモ化された子コンポーネントに渡す関数propsとして渡さない関数
React.memo同じpropsでコンポーネントが頻繁に再レンダリングされる場合レンダリングごとにpropsが変わる場合
なしデフォルト — メモ化しない必ず最初にプロファイリングする

アンチパターン/よくある間違い

アンチパターン問題点正しいアプローチ
データ取得にuseEffectを使う競合状態、キャッシュなし、重複排除なしReact QueryまたはServer Components
2階層を超えるpropsのバケツリレー密結合、保守の負担コンポジション、コンテキスト、またはZustand
コンポーネント内のビジネスロジックテスト不能、再利用不可フックまたはユーティリティ関数に切り出す
バレルエクスポートツリーシェイキングを妨げ、ビルドを遅くする直接インポート
実装の詳細をテストするリファクタリングで壊れる脆いテストユーザーの操作と結果という振る舞いをテストする
どこでもany型を使うTypeScriptの目的を損なうunknownと型ガードを使う
動的でない値にインラインスタイルを使う一貫性がなく、保守しにくいCSS modules、Tailwind、またはstyled-components
すべてをメモ化する複雑さが増し、かえって遅くなることが多いまずプロファイリングし、その後メモ化する

ドキュメントの検索(Context7)

最新のドキュメントを参照するには、mcp__context7__resolve-library-idを実行してからmcp__context7__query-docsを実行してください。返されたドキュメントは、記憶している知識より優先されます。

  • react — フックAPI、コンポーネントのライフサイクル、またはReact 19以降の機能について不明な場合
  • next.js — App Router、Server Components、またはNext.js固有のAPIについて調べる場合
  • typescript — 高度な型のパターンやコンパイラーオプションについて調べる場合
  • tailwindcss — ユーティリティクラス、設定、またはプラグインAPIについて調べる場合
  • vitest — テストランナーAPI、マッチャー、またはモックユーティリティについて調べる場合

統合ポイント

スキル関係
testing-strategyテスト戦略でフロントエンドのテストフレームワークを定義します
test-driven-developmentコンポーネントはTDDサイクルに沿って構築します
react-best-practices詳細なReactのパターンで、このスキルを補完します
performance-optimizationフロントエンドのパフォーマンスは最適化の手法に従います
code-reviewコンポーネントのアーキテクチャとテストカバレッジをレビューします
clean-codeコード品質の原則はコンポーネントのコードにも適用されます
webapp-testingPlaywrightのE2Eテストでは、このスキルのページ構造を使用します
acceptance-testingUIの受け入れ基準に基づいてコンポーネントをテストします

主要な原則

  • TypeScript の厳格モードを使用し、any は使わない(unknown と型ガードを使用する)
  • 継承よりもコンポジションを優先する
  • テスト、スタイル、ストーリーはコンポーネントと同じ場所に配置する
  • デフォルトではサーバーコンポーネントを使用し、クライアントコンポーネントは必要な場合にのみ使用する
  • ルートと機能の境界にエラーバウンダリーを設ける
  • アクセシビリティは必須(axe-core でテストする)

スキルの種類

FLEXIBLE — コンポーネントアーキテクチャと状態管理は、既存プロジェクトの規約に合わせて調整してください。3 フェーズのワークフローを強く推奨します。テストカバレッジは 85% を超える必要があります。TypeScript の厳格モードは必須です。

コメント