libraries-dependencies-mastery
最新のウェブ開発に必要不可欠なライブラリとその依存関係を完全にマスターできます。Next.js、React、TypeScript、Tailwind CSS、Firebase、Zustand、redux-toolkit、react-hook-form、Zod、shadcn/ui、lucide-react、Stripeなど幅広いライブラリをカバーしています。セットアップから統合パターン、高度な使用方法、パフォーマンス最適化、トラブルシューティング、よくある落とし穴、バージョン管理まで網羅しています。クイックリファレンスガイド、詳細なチュートリアル、ECサイトおよびSaaSの完全な実装例、設定ファイル、型定義、エラーハンドリング、本番環境でのパターンを含めた充実した内容です。複数のライブラリの連携方法を理解し、実際のビジネス課題を解決できるようになります。
description の原文を見る
Complete mastery of essential modern web development libraries and dependencies. Cover Next.js, React, TypeScript, Tailwind CSS, Firebase, Zustand, redux-toolkit, react-hook-form, Zod, shadcn/ui, lucide-react, Stripe, and more. Learn setup, integration patterns, advanced usage, performance optimization, troubleshooting, common pitfalls, and version management. Includes quick reference guides, in-depth tutorials, complete examples for e-commerce and SaaS, configuration files, type definitions, error handling, and production patterns. Master how libraries work together and solve real-world challenges.
SKILL.md 本文
ライブラリ & 依存関係の習得
概要
あなたは最新のウェブ開発ライブラリとその統合の専門家です。このスキルは、最新のフルスタックアプリケーションを支える必須ライブラリの完全な習得を提供します:Next.js、React、TypeScript、Tailwind CSS、Firebase、状態管理(Zustand、Redux Toolkit)、フォーム(react-hook-form、Zod)、UI/UX(shadcn/ui、lucide-react)、決済(Stripe)。セットアップ、設定、統合パターン、高度な使用法、パフォーマンス最適化、トラブルシューティング、バージョン管理、および一般的な落とし穴を学びます。
コアライブラリの習得
1. Next.js 13+ 完全習得
セットアップと設定:
- インストールとプロジェクト初期化
- 厳密なTypeScriptのためのtsconfig.json設定
- next.config.jsのカスタマイズ
- 環境変数(.env、.env.local、.env.production)
- パスエイリアス(@/ インポート)
- ワークスペースを使用したモノレポセットアップ
アプリケーションルーター(Next.js 13+):
- ファイルベースのルーティング構造
- ルートセグメントと動的ルート([id]、[...slug])
- ルートグループとレイアウト((auth)、(dashboard))
- 並列ルートと途中割り込みルート
- ローディング状態とエラーバウンダリ
- 見つからないページとerror.jsページ
- ミドルウェアとリクエスト処理
- ルートハンドラー(GET、POST、PUT、DELETE、PATCH)
- サーバーコンポーネント対クライアントコンポーネント
- Suspenseとストリーミング
- データ取得パターン(fetch、キャッシュタグ)
- リバリデーション戦略(ISR、オンデマンド)
パフォーマンス最適化:
- next/imageを使用した画像最適化
- フォント最適化
- スクリプト最適化とローディング戦略
- React.lazyを使用した動的インポート
- コード分割とバンドル分析
- CSS最適化と縮小
- 圧縮とgzip
- CDN設定
一般的な落とし穴と解決策:
- ハイドレーションの不一致(サーバー対クライアント)
- サーバーコンポーネント内でのクライアント専用機能の使用
- 不正なキャッシング戦略
- 画像最適化の問題
- フォント読み込みのパフォーマンス
- 動的ルートが静的にレンダリングされない
- 環境変数のスコープ
トラブルシューティングガイド:
Issue: ビルド時に「Cannot find module」エラー
Solution: tsconfig paths を確認、.next フォルダをクリア、再度ビルド
Issue: ハイドレーション不一致エラー
Solution: 動的インポートを使用、クライアントコードを包装、useEffect を確認
Issue: 画像が最適化されない
Solution: next/image を使用、ドメインを設定、sizes を確認
Issue: ビルド時間が長すぎる
Solution: `next/bundle-analyzer` で分析、動的インポートを使用
Issue: 環境変数が未定義
Solution: NEXT_PUBLIC_ をプレフィックス、クライアント用、開発サーバーを再起動
バージョン管理:
- Pages ルーターからアプリケーションルーターへのアップグレード
- バージョン間の破壊的変更
- マイグレーションガイド
- ベータ機能と廃止予定機能
- リリースに対して最新の状態を保つ
2. React 18+ 完全習得
フックの深堀り:
- useState:状態管理、状態更新、バッチ処理
- useEffect:副作用、クリーンアップ、依存関係、一般的な落とし穴
- useContext:コンテキスト作成、プロップドリリングの回避
- useReducer:複雑な状態ロジック、レデューサーパターン
- useCallback:メモ化、依存関係配列
- useMemo:高負荷計算、メモリ管理
- useRef:DOM アクセス、永続的な値、.current
- useLayoutEffect:DOM レイアウト測定
- useTransition:並行レンダリング、isPending 状態
- useDeferredValue:値のデバウンス、入力最適化
- useId:一意識別子、アクセシビリティ
- useImperativeHandle:カスタムインスタンス値
コンポーネントパターン:
- フックを使用した関数コンポーネント
- カスタムフック開発と再利用性
- 複合コンポーネント
- レンダープロップパターン
- 高階コンポーネント
- プロバイダーパターン
- 制御対非制御コンポーネント
- 継承より合成
パフォーマンス最適化:
- React.memo によるリレンダリング防止
- 依存関係付き useCallback
- 高負荷操作用 useMemo
- React.lazy と Suspense による遅延読み込み
- コード分割戦略
- 安定したキーを使用したリスト レンダリング
- 不要なレンダリングを回避
- Profiler API によるパフォーマンス測定
並行機能:
- Suspense 境界
- 非ブロッキング更新用 useTransition
- 値デバウンス用 useDeferredValue
- ストリーミングと段階的レンダリング
- 状態更新の自動バッチ処理
一般的な落とし穴と解決策:
- useEffect での依存関係の欠落
- フック内の古いクロージャ
- useEffect でのメモリリーク
- useEffect での無限ループ
- 条件付きでのフック使用
- クリーンアップ関数の返却なし
- 不正なメモ依存関係
- 状態バッチ処理の混乱
トラブルシューティングガイド:
Issue: useEffect での無限ループ
Solution: 依存関係を確認、クリーンアップ関数を返却
Issue: コールバック内の状態が古い
Solution: 依存関係に状態を含める、useCallback を使用
Issue: メモリリーク警告
Solution: useEffect にクリーンアップ関数を追加、サブスクリプションを解除
Issue: コンポーネントが不要にリレンダリングされる
Solution: React.memo を使用、useCallback、useMemo を使用
Issue: useId でハイドレーション エラー
Solution: 適切な key プロップを使用、Suspense でラップ
3. TypeScript 完全習得
基礎:
- プリミティブ型(string、number、boolean、null、undefined)
- ユニオン型と交差型
- 型リテラルとリテラル型
- 列挙型と const アサーション
- 型エイリアス対インターフェース
- 型とインターフェースの拡張
- オプショナルプロパティ(?)とヌル合体演算子(??)
高度な型:
- ジェネリック型と制約
- 条件付き型(extends ? :)
- マップされた型(Record、Partial、Required など)
- ユーティリティ型(Pick、Omit、Exclude、Extract など)
- 網羅的チェック用の判別される共用体
- 型ガードと型述語(is キーワード)
- Const 型パラメーター
- テンプレートリテラル型
React + TypeScript:
- コンポーネント プロップの型付け
- イベント ハンドラーの型付け
- Ref<HTMLInputElement> での Ref 型付け
- 初期値による useState と TypeScript
- 型付きアクション付き useReducer
- 型付き値付き useContext
- カスタム フック の型付け
- Children プロップの型付け
一般的なパターン:
// 判別される共用体
type Action =
| { type: 'ADD'; payload: Item }
| { type: 'REMOVE'; payload: string };
// ジェネリック コンポーネント
function List<T extends { id: string }>(props: { items: T[] }) {}
// 型ガード
function isString(value: unknown): value is string {
return typeof value === 'string';
}
// ユーティリティ型の使用
type User = { name: string; age: number; email: string };
type UserPreview = Pick<User, 'name' | 'age'>;
設定:
- tsconfig.json の厳密モード
- 厳密な型チェック用の CompilerOptions
- パスマッピングとエイリアス
- モジュール解決設定
- 宣言ファイル生成
一般的な落とし穴と解決策:
- 型推論の失敗
- 型アサーションの誤用
- Any 型の過度な使用
- 不正なジェネリック制約
- 不足している型定義
- 循環型依存関係
トラブルシューティングガイド:
Issue: 型 'X' を型 'Y' に割り当てられない
Solution: プロパティ名を確認、型アサーションを慎重に使用、インターフェースを確認
Issue: 名前 'X' が見つからない
Solution: インポート、tsconfig paths を確認、node_modules を確認
Issue: プロパティ 'X' が型 'Y' に存在しない
Solution: 型を確認、インターフェースを更新、外部パッケージの型を確認
Issue: ジェネリック型 'T' が複雑すぎる
Solution: 制約を追加、よりシンプルな型に分割、keyof を使用
4. Tailwind CSS 完全習得
コア概念:
- ユーティリティファーストのCSS方法論
- JIT(Just-In-Time)コンパイル
- ブレークポイント(sm、md、lg、xl、2xl)を使用したレスポンシブデザイン
- ホバー、フォーカス、およびその他の状態バリアント
- ダークモード実装(クラスと prefers-color-scheme)
- カスタム設定(色、間隔、フォント)
- 任意の値([width: 343px])
- CSS レイヤーと特異性
設定とカスタマイズ:
// tailwind.config.ts
import type { Config } from 'tailwindcss'
export default {
content: [
'./app/**/*.{js,ts,jsx,tsx}',
'./components/**/*.{js,ts,jsx,tsx}',
],
theme: {
extend: {
colors: {
primary: '#your-color',
},
spacing: {
'128': '32rem',
},
},
},
plugins: [],
} satisfies Config
高度なパターン:
- レスポンシブデザイン戦略
- @apply を使用したコンポーネント抽出
- clsx/classnames による条件付きスタイリング
- ダークモード切り替え
- カスタムプラグイン
- CSS 変数統合
- アニメーションとトランジションユーティリティ
- CSS カスタム プロパティを使用したテーマ切り替え
パフォーマンス最適化:
- 本番環境での未使用スタイルのパージング
- ツリーシェーキング用のコンテンツ設定
- CSS サイズ分析
- クリティカル CSS インライン最適化
- スタイルシートの遅延読み込み
- CSS 圧縮
一般的な落とし穴と解決策:
- ユーティリティの競合と特異性の問題
- Tailwind サイジングでのレスポンシブ画像
- ダークモードが正常に機能しない
- 本番環境で未使用クラスがビルドに含まれる
- カスタム色が適用されない
- 競合する CSS と Tailwind クラス
トラブルシューティングガイド:
Issue: 本番環境でスタイルが適用されない
Solution: content パスを確認、再度ビルド、purge config を確認
Issue: ダークモードが切り替わらない
Solution: config で darkMode: 'class' を設定、html にクラスを追加
Issue: カスタム色が利用できない
Solution: tailwind.config.ts の theme.extend.colors を更新
Issue: ビルド サイズが大きすぎる
Solution: content パスを確認、JIT を使用、未使用プラグインを削除
Issue: レスポンシブスタイルが機能しない
Solution: 正しいブレークポイント プレフィックスを使用(sm:、md:)、カスケードを確認
5. Firebase 完全習得
セットアップと設定:
// lib/firebase.ts
import { initializeApp } from 'firebase/app';
import { getAuth } from 'firebase/auth';
import { getFirestore } from 'firebase/firestore';
import { getStorage } from 'firebase/storage';
const firebaseConfig = {
apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
};
const app = initializeApp(firebaseConfig);
export const auth = getAuth(app);
export const db = getFirestore(app);
export const storage = getStorage(app);
認証:
- メール/パスワードのサインアップとサインイン
- OAuth プロバイダー(Google、GitHub、Facebook)
- ユーザー プロファイル管理
- 認可用カスタムクレーム
- セッション永続化
- トークンリフレッシュと有効期限
- MFA セットアップと検証
- 匿名認証
Firestore データベース:
- コレクション参照とドキュメント参照
- CRUD 操作(作成、読み取り、更新、削除)
- クリーンアップ付きリアルタイムリスナー
- バッチ書き込みとトランザクション
- クエリ操作(where、orderBy、limit)
- startAt/endAt によるページネーション
- サブコレクション対ルートコレクション
- データモデリングと正規化
クラウドストレージ:
- 進行状況追跡付きのファイルアップロード
- ダウンロード URL と署名付き URL
- ファイルの削除と管理
- アクセス制御とセキュリティ ルール
- 画像最適化戦略
- 大容量ファイルの再開可能アップロード
オフライン永続化:
- ローカル キャッシング設定
- 再接続時のサーバーとの同期
- オフライン ファースト戦略
- 競合解決
一般的な落とし穴と解決策:
- セキュリティ ルールがアクセスをブロック
- 欠落している .onSnapshot クリーンアップ
- 不安定なデータによるクエリ
- 過度なサブコレクション作成
- 書き込み前のデータ検証がない
- 矛盾する認証状態
- ストレージ ルールがアップロードを防止
トラブルシューティングガイド:
Issue: 「Permission denied」エラー
Solution: セキュリティ ルール を確認、認証状態を確認、カスタム クレーム を確認
Issue: onSnapshot が更新されない
Solution: リスナーが接続されていることを確認、firestore ルール を確認、適切にクリーンアップ
Issue: ファイル アップロードが失敗
Solution: ストレージ ルール を確認、ファイル パスを確認、バケット パーミッション を確認
Issue: リフレッシュ時に認証状態が未定義
Solution: レンダリング前に onAuthStateChanged を待機、ローディング状態を使用
Issue: リアルタイム リスナーがクォータを消費
Solution: リスナーを制限、once を使用、クリーンアップを実装
6. 状態管理:Zustand & Redux Toolkit
Zustand 完全版:
// store/cartStore.ts
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
interface CartState {
items: CartItem[];
addItem: (item: CartItem) => void;
removeItem: (id: string) => void;
getTotal: () => number;
}
export const useCartStore = create<CartState>()(
persist(
(set, get) => ({
items: [],
addItem: (item) => set(state => ({
items: [...state.items, item]
})),
removeItem: (id) => set(state => ({
items: state.items.filter(i => i.id !== id)
})),
getTotal: () => {
return get().items.reduce((sum, item) =>
sum + item.price * item.quantity, 0
);
},
}),
{ name: 'cart-storage' }
)
);
Redux Toolkit 完全版:
// store/cartSlice.ts
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
interface CartState {
items: CartItem[];
}
const cartSlice = createSlice({
name: 'cart',
initialState: { items: [] },
reducers: {
addItem: (state, action: PayloadAction<CartItem>) => {
state.items.push(action.payload);
},
removeItem: (state, action: PayloadAction<string>) => {
state.items = state.items.filter(i => i.id !== action.payload);
},
},
});
export const { addItem, removeItem } = cartSlice.actions;
export default cartSlice.reducer;
比較と使用時期:
- Zustand:軽量、最小限のボイラープレート、初心者向け
- Redux Toolkit:より強力、DevTools より優れている、大規模アプリ
- 他のライブラリとの統合
- パフォーマンス考慮事項
一般的な落とし穴と解決策:
- Zustand で直接状態を変更
- persist ミドルウェアの不正な使用
- Redux セレクター パフォーマンスの問題
- ストア変更からの不要なリレンダリング
- DevTools が機能しない
トラブルシューティングガイド:
Issue: Zustand で状態が永続化されない
Solution: persist ミドルウェアを追加、localStorage を確認、name prop を確認
Issue: Redux コンポーネントが更新されない
Solution: セレクターを確認、dispatch が呼び出されたことを確認、ミドルウェアを確認
Issue: マウント時にストア データが未定義
Solution: ローディング状態を使用、ハイドレーションを待機、persist を確認
Issue: リスナーからメモリリーク
Solution: サブスクリプション解除関数を返却、useEffect でクリーンアップ
7. フォーム:react-hook-form + Zod
react-hook-form セットアップ:
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
const schema = z.object({
email: z.string().email(),
password: z.string().min(8),
});
type FormData = z.infer<typeof schema>;
function LoginForm() {
const { register, handleSubmit, formState: { errors } } = useForm<FormData>({
resolver: zodResolver(schema),
});
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register('email')} />
{errors.email && <span>{errors.email.message}</span>}
</form>
);
}
Zod バリデーション:
// 完全なバリデーション スキーマ
const userSchema = z.object({
name: z.string().min(2).max(50),
email: z.string().email(),
age: z.number().min(18).max(120),
password: z.string().min(8),
confirmPassword: z.string(),
terms: z.boolean().refine(val => val === true),
}).refine(data => data.password === data.confirmPassword, {
message: "Passwords don't match",
path: ["confirmPassword"],
});
高度なパターン:
- バリデーション付きの複数ステップ フォーム
- 動的フィール配列
- 条件付きフィールド レンダリング
- 非同期バリデーション(メール可用性確認)
- カスタム バリデーター
- ネストされたオブジェクト バリデーション
- ファイル アップロード バリデーション
- フォーム送信処理
一般的な落とし穴と解決策:
- バリデーション エラー時にフォームが送信される
- 非同期バリデーションが遅延を引き起こす
- Zod スキーマがフォーム構造と一致しない
- フィール配列の複雑性
- カスタム バリデーション ロジックのエラー
- フォーム リセットが機能しない
- ファイル アップロード バリデーションが失敗
トラブルシューティングガイド:
Issue: エラーがあってもフォームが送信される
Solution: handleSubmit の使用を確認、resolver の設定を確認
Issue: 非同期バリデーションが長すぎる
Solution: デバウンスを追加、キャッシングを実装、バックエンドを最適化
Issue: Zod エラー:「Expected object, received undefined」
Solution: スキーマがフォーム データ構造と一致することを確認
Issue: 動的フィールが バリデーション されない
Solution: z.array() を正しく使用、スキーマを動的に更新
Issue: ファイル バリデーションが機能しない
Solution: refine/superRefine を使用、ファイル型バリデーションを確認
8. UI/UX:shadcn/ui & lucide-react
shadcn/ui セットアップと使用:
// 事前構築コンポーネントの使用
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Card } from '@/components/ui/card';
export function MyComponent() {
return (
<Card>
<Input placeholder="Enter text" />
<Button>Submit</Button>
</Card>
);
}
利用可能なコンポーネント:
- ボタン(バリアント、サイズ、状態)
- 入力フィールドとフォーム
- カード とコンテナー
- モーダルとダイアログ
- ドロップダウンとメニュー
- タブとアコーディオン
- データ テーブルとリスト
- アラートと通知
- 進行状況インジケーター
- ナビゲーション コンポーネント
- ツールチップとポップオーバー
lucide-react アイコン:
import { Heart, ShoppingCart, Menu, X } from 'lucide-react';
export function IconExample() {
return (
<>
<Heart size={24} />
<ShoppingCart className="text-blue-600" />
<Menu strokeWidth={1.5} />
</>
);
}
カスタマイズとテーマ:
- Tailwind CSS 統合
- 色のカスタマイズ
- サイズ バリアント
- アニメーション オプション
- ダークモード サポート
- カスタム コンポーネント ラッパー
一般的な落とし穴と解決策:
- コンポーネント スタイル競合
- アイコン サイズの矛盾
- アクセシビリティの問題
- テーマが適用されない
- カスタム スタイルがデフォルトをオーバーライド
トラブルシューティングガイド:
Issue: shadcn/ui コンポーネント スタイルが適用されない
Solution: Tailwind config を確認、CSS インポートを確認、className 競合を確認
Issue: アイコンが表示されないか、サイズが正しくない
Solution: size prop を指定、インポート パスを確認、CSS クラスを確認
Issue: ダークモードがコンポーネントで機能しない
Solution: tailwind.config で darkMode を設定、プロバイダーでラップ
Issue: コンポーネント バリアントが機能しない
Solution: コンポーネント prop 名を確認、バージョン互換性を確認
9. 決済:Stripe 統合
Stripe セットアップ:
import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
// 支払いインテント作成
const paymentIntent = await stripe.paymentIntents.create({
amount: 1000, // セント単位
currency: 'usd',
payment_method_types: ['card'],
});
クライアント側統合:
import { loadStripe } from '@stripe/js';
import { CardElement, useStripe, useElements } from '@stripe/react-stripe-js';
const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_KEY!);
function PaymentForm() {
const stripe = useStripe();
const elements = useElements();
const handleSubmit = async (e) => {
const { paymentIntent } = await stripe.confirmCardPayment(
clientSecret,
{ payment_method: { card: elements.getElement(CardElement) } }
);
};
return (
<Elements stripe={stripePromise}>
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- majiayu000
- ライセンス
- MIT
- 最終更新
- 2026/5/4
Source: https://github.com/majiayu000/claude-skill-registry / ライセンス: MIT