mcpField
S
senior-frontend

senior-frontend

github.com/sickn33開発49.1k269 回インストール今日更新
リポジトリ

senior-frontend について

senior-frontendは、ReactとNext.jsの開発者向けのフロントエンド開発スキルです。プロジェクトやコンポーネントの生成に加え、バンドル分析、最適化、アクセシビリティ確認、テストの指針を扱います。

主な機能

  1. 01ReactとNext.jsのプロジェクト生成
  2. 02TypeScriptコンポーネントとフックの生成
  3. 03バンドル分析と改善提案
  4. 04ReactとNext.jsのパターン指針
  5. 05アクセシビリティとテストのチェックリスト

活用シーン

  1. 01ReactまたはNext.jsアプリのひな形作成
  2. 02テストやStorybook付きコンポーネントの生成
  3. 03プロジェクト内の大きな依存関係の特定
  4. 04アクセシビリティとフロントエンドテストの確認

インストール

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

$npx skills add https://github.com/sickn33/agentic-awesome-skills --skill senior-frontend

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

同梱ファイル

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

references/
frontend_best_practices.md
nextjs_optimization_guide.md
react_patterns.md
scripts/
component_generator.py
bundle_analyzer.py
frontend_scaffolder.py

詳細

シニアフロントエンド

React/Next.js アプリケーション向けのフロントエンド開発パターン、パフォーマンス最適化、自動化ツールです。

使用する場面

  • TypeScript と Tailwind CSS を使用して新しい React または Next.js プロジェクトをスキャフォールディングするときに使用します。
  • 新しいコンポーネントやカスタムフックを生成するときに使用します。
  • フロントエンドアプリケーションのバンドルサイズを分析し、最適化するときに使用します。
  • Compound Components や Render Props などの高度な React パターンを実装またはレビューするときに使用します。
  • アクセシビリティへの準拠を確保し、堅牢なテスト戦略を実装するときに使用します。

目次


プロジェクトのスキャフォールディング

TypeScript、Tailwind CSS、ベストプラクティスに基づく設定を使用して、新しい Next.js または React プロジェクトを生成します。

ワークフロー:新しいフロントエンドプロジェクトの作成
  1. プロジェクト名とテンプレートを指定してスキャフォールダーを実行します。

    python scripts/frontend_scaffolder.py my-app --template nextjs
    
  2. オプション機能(認証、API、フォーム、テスト、Storybook)を追加します。

    python scripts/frontend_scaffolder.py dashboard --template nextjs --features auth,api
    
  3. プロジェクトに移動して依存関係をインストールします。

    cd my-app && npm install
    
  4. 開発サーバーを起動します。

    npm run dev
    
スキャフォールダーのオプション
オプション説明
--template nextjsApp Router と Server Components を備えた Next.js 14 以降
--template reactTypeScript を使用した React + Vite
--features authNextAuth.js 認証を追加
--features apiReact Query + API クライアントを追加
--features formsReact Hook Form + Zod バリデーションを追加
--features testingVitest + Testing Library を追加
--dry-runファイルを作成せずにプレビュー
生成される構成(Next.js)
my-app/
├── app/
│   ├── layout.tsx        # Root layout with fonts
│   ├── page.tsx          # Home page
│   ├── globals.css       # Tailwind + CSS variables
│   └── api/health/route.ts
├── components/
│   ├── ui/               # Button, Input, Card
│   └── layout/           # Header, Footer, Sidebar
├── hooks/                # useDebounce, useLocalStorage
├── lib/                  # utils (cn), constants
├── types/                # TypeScript interfaces
├── tailwind.config.ts
├── next.config.js
└── package.json

コンポーネントの生成

TypeScript、テスト、Storybook ストーリーを含む React コンポーネントを生成します。

ワークフロー:新しいコンポーネントの作成
  1. クライアントコンポーネントを生成します。

    python scripts/component_generator.py Button --dir src/components/ui
    
  2. サーバーコンポーネントを生成します。

    python scripts/component_generator.py ProductCard --type server
    
  3. テストファイルとストーリーファイルを含めて生成します。

    python scripts/component_generator.py UserProfile --with-test --with-story
    
  4. カスタムフックを生成します。

    python scripts/component_generator.py FormValidation --type hook
    
ジェネレーターのオプション
オプション説明
--type client'use client' を指定したクライアントコンポーネント(デフォルト)
--type server非同期サーバーコンポーネント
--type hookカスタム React フック
--with-testテストファイルを含める
--with-storyStorybook ストーリーを含める
--flatサブディレクトリを作成せず、出力ディレクトリに作成
--dry-runファイルを作成せずにプレビュー
生成されるコンポーネントの例
"use client";

import { useState } from "react";
import { cn } from "@/lib/utils";

interface ButtonProps {
  className?: string;
  children?: React.ReactNode;
}

export function Button({ className, children }: ButtonProps) {
  return <div className={cn("", className)}>{children}</div>;
}

バンドル分析

package.json とプロジェクト構成を分析し、バンドル最適化の機会を特定します。

ワークフロー:バンドルサイズの最適化
  1. プロジェクトでアナライザーを実行します。

    python scripts/bundle_analyzer.py /path/to/project
    
  2. ヘルススコアと問題点を確認します。

    Bundle Health Score: 75/100 (C)
    
    HEAVY DEPENDENCIES:
      moment (290KB)
        Alternative: date-fns (12KB) or dayjs (2KB)
    
      lodash (71KB)
        Alternative: lodash-es with tree-shaking
    
  3. 推奨される修正を適用し、サイズの大きい依存関係を置き換えます。

  4. verbose モードで再実行し、インポートパターンを確認します。

    python scripts/bundle_analyzer.py . --verbose
    
バンドルスコアの解釈
スコア評価対応
90-100Aバンドルは十分に最適化されています
80-89B軽微な最適化の余地があります
70-79Cサイズの大きい依存関係を置き換えます
60-69D複数の問題への対応が必要です
0-59Fバンドルサイズに重大な問題があります
重い依存関係の検出

アナライザーは、次のような一般的なサイズの大きいパッケージを特定します。

パッケージサイズ代替案
moment290KBdate-fns (12KB) または dayjs (2KB)
lodash71KBツリーシェイキング対応の lodash-es
axios14KBネイティブの fetch または ky (3KB)
jquery87KBネイティブの DOM API
@mui/material大shadcn/ui または Radix UI

React のパターン

参照先:references/react_patterns.md

複合コンポーネント

関連するコンポーネント間で状態を共有します。

const Tabs = ({ children }) => {
  const [active, setActive] = useState(0);
  return (
    <TabsContext.Provider value={{ active, setActive }}>
      {children}
    </TabsContext.Provider>
  );
};

Tabs.List = TabList;
Tabs.Panel = TabPanel;

// Usage
<Tabs>
  <Tabs.List>
    <Tabs.Tab>One</Tabs.Tab>
    <Tabs.Tab>Two</Tabs.Tab>
  </Tabs.List>
  <Tabs.Panel>Content 1</Tabs.Panel>
  <Tabs.Panel>Content 2</Tabs.Panel>
</Tabs>;
カスタムフック

再利用可能なロジックを切り出します。

function useDebounce<T>(value: T, delay = 500): T {
  const [debouncedValue, setDebouncedValue] = useState(value);

  useEffect(() => {
    const timer = setTimeout(() => setDebouncedValue(value), delay);
    return () => clearTimeout(timer);
  }, [value, delay]);

  return debouncedValue;
}

// Usage
const debouncedSearch = useDebounce(searchTerm, 300);
レンダープロップ

レンダリングロジックを共有します。

function DataFetcher({ url, render }) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetch(url)
      .then((r) => r.json())
      .then(setData)
      .finally(() => setLoading(false));
  }, [url]);

  return render({ data, loading });
}

// Usage
<DataFetcher
  url="/api/users"
  render={({ data, loading }) =>
    loading ? <Spinner /> : <UserList users={data} />
  }
/>;

Next.js の最適化

参照先:references/nextjs_optimization_guide.md

サーバーコンポーネントとクライアントコンポーネント

デフォルトではサーバーコンポーネントを使用してください。次の機能が必要な場合にのみ、'use client' を追加します。

  • イベントハンドラー(onClick、onChange)
  • 状態(useState、useReducer)
  • エフェクト(useEffect)
  • ブラウザー API
// Server Component (default) - no 'use client'
async function ProductPage({ params }) {
  const product = await getProduct(params.id); // Server-side fetch

  return (
    <div>
      <h1>{product.name}</h1>
      <AddToCartButton productId={product.id} /> {/* Client component */}
    </div>
  );
}

// Client Component
"use client";
function AddToCartButton({ productId }) {
  const [adding, setAdding] = useState(false);
  return <button onClick={() => addToCart(productId)}>Add</button>;
}
画像の最適化
import Image from 'next/image';

// Above the fold - load immediately
<Image
  src="/hero.jpg"
  alt="Hero"
  width={1200}
  height={600}
  priority
/>

// Responsive image with fill
<div className="relative aspect-video">
  <Image
    src="/product.jpg"
    alt="Product"
    fill
    sizes="(max-width: 768px) 100vw, 50vw"
    className="object-cover"
  />
</div>
データ取得のパターン
// Parallel fetching
async function Dashboard() {
  const [user, stats] = await Promise.all([getUser(), getStats()]);
  return <div>...</div>;
}

// Streaming with Suspense
async function ProductPage({ params }) {
  return (
    <div>
      <ProductDetails id={params.id} />
      <Suspense fallback={<ReviewsSkeleton />}>
        <Reviews productId={params.id} />
      </Suspense>
    </div>
  );
}

アクセシビリティとテスト

参照先:references/frontend_best_practices.md

アクセシビリティのチェックリスト
  1. セマンティック HTML:適切な要素(<button>、<nav>、<main>)を使用します
  2. キーボード操作:すべてのインタラクティブな要素をフォーカス可能にします
  3. ARIA ラベル:アイコンや複雑なウィジェットにラベルを指定します
  4. 色のコントラスト:通常のテキストでは最低 4.5:1 にします
  5. フォーカスインジケーター:フォーカス状態を視覚的に示します
// Accessible button
<button
  type="button"
  aria-label="Close dialog"
  onClick={onClose}
  className="focus-visible:ring-2 focus-visible:ring-blue-500"
>
  <XIcon aria-hidden="true" />
</button>

// Skip link for keyboard users
<a href="#main-content" className="sr-only focus:not-sr-only">
  Skip to main content
</a>
テスト戦略
// Component test with React Testing Library
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";

test("button triggers action on click", async () => {
  const onClick = vi.fn();
  render(<Button onClick={onClick}>Click me</Button>);

  await userEvent.click(screen.getByRole("button"));
  expect(onClick).toHaveBeenCalledTimes(1);
});

// Test accessibility
test("dialog is accessible", async () => {
  render(<Dialog open={true} title="Confirm" />);

  expect(screen.getByRole("dialog")).toBeInTheDocument();
  expect(screen.getByRole("dialog")).toHaveAttribute("aria-labelledby");
});

クイックリファレンス

Next.js の一般的な設定
// next.config.js
const nextConfig = {
  images: {
    remotePatterns: [{ hostname: "cdn.example.com" }],
    formats: ["image/avif", "image/webp"],
  },
  experimental: {
    optimizePackageImports: ["lucide-react", "@heroicons/react"],
  },
};
Tailwind CSS のユーティリティ
// Conditional classes with cn()
import { cn } from "@/lib/utils";

<button
  className={cn(
    "px-4 py-2 rounded",
    variant === "primary" && "bg-blue-500 text-white",
    disabled && "opacity-50 cursor-not-allowed",
  )}
/>;
TypeScript のパターン
// Props with children
interface CardProps {
  className?: string;
  children: React.ReactNode;
}

// Generic component
interface ListProps<T> {
  items: T[];
  renderItem: (item: T) => React.ReactNode;
}

function List<T>({ items, renderItem }: ListProps<T>) {
  return <ul>{items.map(renderItem)}</ul>;
}

リソース

  • React のパターン:references/react_patterns.md
  • Next.js の最適化:references/nextjs_optimization_guide.md
  • ベストプラクティス:references/frontend_best_practices.md

制限事項

  • 上記で説明されている範囲にタスクが明確に該当する場合にのみ、このスキルを使用してください。
  • 出力を、環境固有の検証、テスト、または専門家によるレビューの代わりとして扱わないでください。
  • 必要な入力、権限、安全上の境界、または成功基準が不足している場合は、作業を中断して確認を求めてください。

スナップショットに関する制限事項

例は抜粋であり、本番環境での認証を保証するものではありません。スキャフォルダーの依存関係は、過去の Next14/React18/Tailwind3 を対象としており、インストール前にサポート対象でパッチ適用済みの依存関係プランが必要です。オプションのスキャフォールド機能テンプレートは未完成のため、現在は生成が拒否されます。生成される React/Vite の設定には、対応するエイリアス、TSX 設定、lint 設定が必要です。認証にはフロントエンドの HOC ではなく、サーバー側の強制適用が必要です。コンポーネントとテストは、アプリケーションのインポート、スタイル、フィクスチャを前提としています。バンドルスコアと KB の表は参考用の経験則であり、実測値でも、パッケージの自動置換の根拠でもありません。

クライアントコンポーネントはサーバーで事前レンダリングされる場合があります。localStorage の初期化子はハイドレーションの不一致を引き起こす可能性があるため、マウント後にローディング境界を設けて読み込み、エラーやキーの変更を処理してください。useAsync/DataFetcher の例には、キャンセル、古いレスポンスへの対処、エラー処理が必要です。カスタムのセレクト/ダイアログの例では、完全なキーボード操作、フォーカスの復元、背景の inert 化が省略されています。テスト済みのプリミティブを優先してください。ベアラートークンを localStorage に保存せず、ログアウト時にセッションデータを消去し、API ルートで認可を強制してください。ユーザーまたはテナントごとにスコープを設定したキーを使わずに、ユーザー固有のキャッシュデータを共有しないでください。params、fetch のキャッシュ、revalidateTag、Image のプリロード、動的 SSR API を、インストールされている Next のバージョンに合わせてください。

コメント