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