mcpField
G
graphql-codegen

graphql-codegen

github.com/claude-dev-suite開発4664 回インストール2 日前に更新
リポジトリ

graphql-codegen について

TypeScript 開発者向けの GraphQL Code Generator 参照スキルで、設定、型生成、クライアント連携を扱います。GraphQL スキーマと操作ドキュメントから型安全なコードを生成するプロジェクトに適しています。

主な機能

  1. 01CLI の設定とコード生成
  2. 02クライアントプリセットと型生成
  3. 03TanStack Query 連携
  4. 04フラグメントのコロケーション
  5. 05複数スキーマの設定
  6. 06CI とウォッチモード

活用シーン

  1. 01スキーマと操作ドキュメントから TypeScript コードを生成
  2. 02GraphQL 操作用のクエリフックを生成
  3. 03開発中にドキュメントを監視して再生成

MCP 対応

`mcp__documentation__fetch_docs` で graphql-codegen の詳細ドキュメントを取得できると記載されています。

インストール

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

$npx skills add https://github.com/claude-dev-suite/claude-dev-suite --skill graphql-codegen

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

同梱ファイル

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

quick-ref/
client-preset.md
react-query.md
typed-document-node.md

詳細

GraphQL Code Generator の基本知識

詳細な知識:包括的なドキュメントについては、technology に graphql-codegen を指定して mcp__documentation__fetch_docs を使用してください。

インストール

npm install -D @graphql-codegen/cli @graphql-codegen/typescript \
  @graphql-codegen/typescript-operations @graphql-codegen/client-preset

基本設定

// codegen.ts
import type { CodegenConfig } from '@graphql-codegen/cli';

const config: CodegenConfig = {
  schema: 'http://localhost:4000/graphql',
  documents: ['src/**/*.tsx', 'src/**/*.ts'],
  ignoreNoDocuments: true,
  generates: {
    './src/gql/': {
      preset: 'client',
      config: {
        documentMode: 'string',
      },
    },
  },
};

export default config;

生成の実行

npx graphql-codegen
npx graphql-codegen --watch  # Watch mode

Client プリセット(推奨)

client プリセットは、型安全な GraphQL に必要なものをすべて生成します。

// codegen.ts
const config: CodegenConfig = {
  schema: 'http://localhost:4000/graphql',
  documents: ['src/**/*.tsx'],
  generates: {
    './src/gql/': {
      preset: 'client',
      plugins: [],
      presetConfig: {
        gqlTagName: 'gql',
        fragmentMasking: { unmaskFunctionName: 'getFragmentData' },
      },
    },
  },
};
使用方法
import { gql } from '../gql';
import { useQuery } from '@apollo/client';

const GET_USER = gql(`
  query GetUser($id: ID!) {
    user(id: $id) {
      id
      name
      email
    }
  }
`);

function UserProfile({ id }: { id: string }) {
  const { data, loading } = useQuery(GET_USER, {
    variables: { id },
  });

  if (loading) return <Spinner />;
  // data.user is fully typed
  return <div>{data?.user?.name}</div>;
}

TanStack Query との統合

npm install -D @graphql-codegen/typescript-react-query
// codegen.ts
const config: CodegenConfig = {
  schema: 'http://localhost:4000/graphql',
  documents: ['src/**/*.graphql'],
  generates: {
    './src/gql/index.ts': {
      plugins: [
        'typescript',
        'typescript-operations',
        'typescript-react-query',
      ],
      config: {
        fetcher: {
          func: './fetcher#fetcher',
          isReactHook: false,
        },
        reactQueryVersion: 5,
        addInfiniteQuery: true,
      },
    },
  },
};
フェッチャー
// src/gql/fetcher.ts
export const fetcher = <TData, TVariables>(
  query: string,
  variables?: TVariables
): (() => Promise<TData>) => {
  return async () => {
    const response = await fetch('http://localhost:4000/graphql', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${getToken()}`,
      },
      body: JSON.stringify({ query, variables }),
    });

    const json = await response.json();
    if (json.errors) {
      throw new Error(json.errors[0].message);
    }
    return json.data;
  };
};
生成されたフックの使用方法
import { useGetUserQuery, useCreateUserMutation } from './gql';

function UserProfile({ id }: { id: string }) {
  const { data, isLoading } = useGetUserQuery({ id });
  const createMutation = useCreateUserMutation();

  const handleCreate = () => {
    createMutation.mutate({
      input: { name: 'John', email: '[email protected]' },
    });
  };

  if (isLoading) return <Spinner />;
  return <div>{data?.user?.name}</div>;
}

フラグメントのコロケーション

// components/UserAvatar.tsx
import { gql, FragmentType, getFragmentData } from '../gql';

export const USER_AVATAR_FRAGMENT = gql(`
  fragment UserAvatar on User {
    id
    name
    avatarUrl
  }
`);

interface Props {
  user: FragmentType<typeof USER_AVATAR_FRAGMENT>;
}

export function UserAvatar({ user }: Props) {
  const data = getFragmentData(USER_AVATAR_FRAGMENT, user);
  return <img src={data.avatarUrl} alt={data.name} />;
}

// Usage in parent query
const GET_USER = gql(`
  query GetUser($id: ID!) {
    user(id: $id) {
      id
      ...UserAvatar
    }
  }
`);

本番環境への対応

スキーマのポーリング
// codegen.ts
const config: CodegenConfig = {
  schema: [
    {
      'http://localhost:4000/graphql': {
        headers: {
          Authorization: `Bearer ${process.env.GRAPHQL_TOKEN}`,
        },
      },
    },
  ],
  // ...
};
複数のスキーマ
const config: CodegenConfig = {
  generates: {
    './src/gql/user-api/': {
      schema: 'http://user-api:4000/graphql',
      documents: ['src/features/user/**/*.tsx'],
      preset: 'client',
    },
    './src/gql/product-api/': {
      schema: 'http://product-api:4001/graphql',
      documents: ['src/features/product/**/*.tsx'],
      preset: 'client',
    },
  },
};
CI/CD との統合
# .github/workflows/codegen.yml
name: GraphQL Codegen

on:
  push:
    paths:
      - 'src/**/*.graphql'
      - 'src/**/*.tsx'

jobs:
  generate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npx graphql-codegen
      - name: Check for changes
        run: |
          if [[ -n $(git status --porcelain src/gql) ]]; then
            echo "Generated files changed"
            exit 1
          fi
パッケージスクリプト
{
  "scripts": {
    "codegen": "graphql-codegen",
    "codegen:watch": "graphql-codegen --watch"
  }
}
チェックリスト
  • スキーマソースが設定されている(URL またはローカル)
  • ドキュメントのパスがソースファイルと一致している
  • 最適な出力のために client プリセットを使用している
  • フェッチャーに認証が設定されている
  • フラグメントのコロケーションパターンを採用している
  • 開発時にウォッチモードを使用している
  • CI で生成コードを検証している
  • TypeScript の strict モードと互換性がある

このスキルを使用しない場合

  • REST API の型生成(openapi-codegen スキルを使用)
  • tRPC の型安全な API(trpc スキルを使用)
  • GraphQL スキーマの設計(graphql スキルを使用)
  • TypeScript 以外のプロジェクト
  • 型生成が不要な単純な GraphQL クエリ

アンチパターン

アンチパターン問題点解決策
生成ファイルを git にコミットするマージの競合、型の陳腐化.gitignore に追加し、CI で生成する
client プリセットを使用しない設定が冗長になる最新の構成では client プリセットを使用する
スキーマの変更を無視する実行時に型が一致しなくなる開発中はウォッチモードで codegen を実行する
operationId またはクエリ名がない生成されるフック名の品質が低下するすべてのクエリ/ミューテーションに名前を付ける
フラグメントを使用しないコードが重複する再利用可能なフィールドにはフラグメントを使用する
型だけを生成する実行時の検証が行われないスキーマ検証と組み合わせる
スキーマ URL をハードコードする環境に依存するスキーマソースには環境変数を使用する
ジェネレーターパッケージをバージョン固定しないチーム内で出力にばらつきが生じるジェネレーターのバージョンを固定する

クイックトラブルシューティング

問題考えられる原因解決策
生成に失敗するスキーマまたはドキュメントが無効スキーマを検証し、GraphQL の構文を確認する
生成後に型エラーが発生するスキーマとコードが一致していない型を再生成し、スキーマの変更を確認する
型が不足しているドキュメントのパスがファイルと一致していないドキュメントの glob パターンを確認する
operation 名が重複している複数のファイルで同じクエリ名を使用しているoperation 名を一意にする
フラグメントが見つからないドキュメントにフラグメントが含まれていないドキュメントにフラグメントファイルを含める
フックが生成されないReact Query プラグインを使用していないtypescript-react-query プラグインを追加する
"Cannot find module './gql'"生成処理が実行されていないnpm run codegen を実行する
生成が遅いドキュメントが多すぎるglob パターンを最適化し、ignoreNoDocuments を使用する
型推論が機能しないインポートパスが誤っている生成された gql フォルダーからインポートする

参考ドキュメント

コメント