Next.jsにcodegenを導入した際に詰まった際の対応まとめ
はじめに
GaraphQL初心者のため詰まった点などをメモしておきます。
環境は以下です。
"graphql": "^16.9.0",
"@apollo/client": "^3.11.8",
"@graphql-codegen/cli": "^5.0.2",
"@graphql-codegen/client-preset": "^4.3.3",
"@parcel/watcher": "^2.4.1",
"typescript": "^5.5.4",
"next": "^14.2.8",
"react": "^18.3.1",
| 種別 | 選定技術 |
|---|---|
| GraphQLクライアント | Apollo Client |
| 型生成ライブラリ | GraphQL Code Generator(client-preset) |
| GraphQL CMS | hygraph |
クエリから型が出力されない場合
事象
クエリファイルからcodegen generateの出力が失敗する。
確認方法(対応方法)
ignoreNoDocumentsプロパティをfalseに
基本はignoreNoDocumentsプロパティはtrueのことが多いと思いますが、falseにすることによってcodegenのwatchなどでクエリが見つからない場合はエラー文を表示し強制終了してくれます。
これによってクエリが間違っていないか、schemaが正しいか、documentsのパスがあっているかがわかります。
- ignoreNoDocuments: true,
+ ignoreNoDocuments: false,
verboseプロパティを追加
上記エラーが出ても詳細が掴みづらいケースがあるため、verboseプロパティを追加することによって詳細なデバックができるようになります。
+ verbose: true
このようにエラー時にbashに記載されます。
[STARTED] Parse Configuration
[SUCCESS] Parse Configuration
[STARTED] Generate outputs
[STARTED] Generate to ./src/gql/
[STARTED] Load GraphQL schemas
[SUCCESS] Load GraphQL schemas
[STARTED] Load GraphQL documents
[FAILED]
[FAILED] Unable to find any GraphQL type definitions for the following pointers:
[FAILED]
[FAILED] - src/gql/query/*.graphql
[FAILED]
documentsプロパティのパスがgenerateのパスと同様になっていないか
以下エラーが出た際にはその可能性が高いと思われます。
恐らくは生成先のパスに対してクエリを参照しにいくことになるので循環参照的なものになっていそうですかね?
Unable to find any GraphQL type definitions for the following pointers:
その場合はdocumentsプロパティのパスとクエリファイルを格納するパスを以下のように変更する必要があります。
のパスを以下のように変更す
const config: CodegenConfig = {
schema: `https://${process.env.HYGRAPH_REGION}.cdn.hygraph.com/content/${process.env.HYGRAPH_ID}/master`,
- documents: ['src/gql/query/*.graphql'], // クエリがある階層を識別しそこから型を生成する
+ documents: ['query/*.graphql'], // クエリがある階層を識別しそこから型を生成する
ignoreNoDocuments: false, // watchした際にクエリが見つからない場合に終了しないように定義
generates: {
'./src/gql/': { // 型ファイルの生成ディレクトリ
preset: 'client', // プリセットリストをクライアントで対応
plugins: [],
}
},
verbose: true
}
graphql拡張子ファイルのクエリを使用する
事象
クエリを記載しているファイルの拡張子がtsやtsxではなく、graphqlの場合どのように対応が必要なのか。
個人的に感じていた疑問点
- garaphqlファイルには
exportなどがないけれどどのようにimportしてpostリクエストするのか -
useQueryをそもそも使用するのか
確認方法(対応方法)
@graphql-codegen/typescript-react-apolloのインストール
そもそもgaraphqlファイルをtsxファイルなどと同様にimportすることはできないため、useQueryは経由せず、hooksをcodegen generateで直接的に生成する必要があります。そこでプラグインごとに役割を整理すると以下です。
そのため、別途@graphql-codegen/typescript-react-apolloをインストールする必要がありました。
| プラグイン | 機能 |
|---|---|
| @graphql-codegen/client-preset | GraphQLのクエリなどから型生成 |
| @graphql-codegen/typescript-react-apollo | GraphQLのクエリからhooksの生成 |
なのでcodege.tsは以下のようになり、configプロパティのwithHooks: trueを記載することでhooksを出力してくれます。
const config: CodegenConfig = {
schema: `https://${process.env.HYGRAPH_REGION}.cdn.hygraph.com/content/${process.env.HYGRAPH_ID}/master`,
+ documents: ['query/*.graphql'], // クエリがある階層を識別しそこから型を生成する
ignoreNoDocuments: false, // watchした際にクエリが見つからない場合に終了しないように定義
generates: {
'./src/gql/': { // 型ファイルの生成ディレクトリ
preset: 'client', // プリセットリストをクライアントで対応
plugins: [
+ 'typescript-react-apollo',
],
+ config: {
+ withHooks: true,
+ withHOC: false,
+ withComponent: false,
}
}
},
verbose: true
}
export default config
上記codegen.tsのcodegen generateによって./src/gql/graphql.tsにhooksが出力されました。これを使用してデータが取得できました。
追記
調べたところclient-presetとplugin両方でdocumentを作成しマージし出力されるためどちらかのみにする必要があります。
client-presetのみにする場合はクエリの記述をgraphqlファイルからts,tsxファイルへ変更するのみなので割愛しますが、pluginを使用する場合は以下です。
const config: CodegenConfig = {
schema: `https://${process.env.HYGRAPH_REGION}.cdn.hygraph.com/content/${process.env.HYGRAPH_ID}/master`,
documents: ['query/*.graphql'], // クエリがある階層を識別しそこから型を生成する
ignoreNoDocuments: false, // watchした際にクエリが見つからない場合に終了しないように定義
generates: {
- './src/gql/': { // 型ファイルの生成ディレクトリ
+ './src/gql/graphql.ts': { // 型ファイルの生成ディレクトリ
- preset: 'client', // プリセットリストをクライアントで対応
plugins: [
+ 'typescript',
+ 'typescript-operations',
'typescript-react-apollo',
],
config: {
withHooks: true,
withHOC: false,
withComponent: false,
}
}
},
verbose: true
}
export default config
まとめ
そもそもクエリはtsファイルなどで管理した方が良いのか、それともgaraphqlファイルで管理の方が良いのかから別途調査していきたいと思います。
恐らくはクエリ文などの見やすさの観点な気がしますが。。。
Discussion