GatsbyJS + microCMSにGraphQL Code Generatorを使って型安全な開発をする
こんにちはhiro08です。
もし、GatsbyJS + microCMS + TypeScriptで開発を行ってる場合、GraphQL Code Generator
を使って型安全にすることをオススメします。なぜなら、GraphQLのクエリに対する型定義は複雑で手間のかかる作業になってしまうからです。
GraphQL Code Generator
を使えば、少ない設定で型定義を自動生成してくれます。今回は型安全に開発する一例をピックアップします。
前提
microCMSの公式が出している、gatsby-source-microcms
を使っている前提で話を進めていきます。
コンテンツモデルは、endpoint
にblog
が設定されている前提を話を進めていきます。
セットアップ
まずは必要なパッケージをインストールします。
$ yarn add -D @graphql-codegen/cli @graphql-codegen/typescript @graphql-codegen/typescript-operations
そして、型定義を作成するための設定ファイルを作りましょう。codegen.yml
というファイル名にします。
overwrite: true
schema: "http://localhost:8000/___graphql"
documents:
- "node_modules/gatsby-source-microcms/!(node_modules)/**/*.js"
- "./src/**/*.{ts,tsx}"
generates:
src/graphqlTypes.ts:
plugins:
- "typescript"
- "typescript-operations"
次にpackage.jsonに型定義を作成するためのコマンドを追加します。
"scripts": {
"generate": "graphql-codegen --config codegen.yml",
}
実際に開発サーバーを立ち上げてから、generate
コマンドを実行すると型定義を生成してくれます。
開発サーバーを立ち上げます。
$ yarn develop
そして、開発サーバーを立ち上げた状態でgenerate
します。
$ yarn generate
成功すると、srcフォルダ
にgraphqlTypes.ts
が作成されます。たったこれだけの設定で型定義を作成することができました。
生成された型定義
実際にgraphqlTypes.ts
の中身を見てみましょう。ページの一覧や、個別ページに必要な型定義を自動的に作成することができました。
// 個別ページに使う型定義
export type MicrocmsBlog = Node & {
__typename?: 'MicrocmsBlog';
id: Scalars['ID'];
parent?: Maybe<Node>;
children: Array<Node>;
internal: Internal;
createdAt?: Maybe<Scalars['Date']>;
updatedAt?: Maybe<Scalars['Date']>;
publishedAt?: Maybe<Scalars['Date']>;
revisedAt?: Maybe<Scalars['Date']>;
title?: Maybe<Scalars['String']>;
body?: Maybe<Scalars['String']>;
blogId?: Maybe<Scalars['String']>;
gatsbyPath?: Maybe<Scalars['String']>;
};
// 一覧ページに使う型定義
export type MicrocmsBlogConnection = {
__typename?: 'MicrocmsBlogConnection';
totalCount: Scalars['Int'];
edges: Array<MicrocmsBlogEdge>;
nodes: Array<MicrocmsBlog>;
pageInfo: PageInfo;
distinct: Array<Scalars['String']>;
group: Array<MicrocmsBlogGroupConnection>;
};
こちらは生成された型定義を使うための、一覧ページの型付け例です。
import React from "react"
import { graphql, Link } from "gatsby"
import { Layout } from "../components/layout"
import { MicrocmsBlogConnection } from "../graphqlTypes"
type Props = {
data: {
allMicrocmsBlog: MicrocmsBlogConnection
}
}
const IndexPage: React.FC<Props> = ({ data }) => (
<Layout>
{data.allMicrocmsBlog.edges.map(({ node }) => (
<React.Fragment key={node.id}>
<Link to={`/blog/${node.blogId}`}>{node.title}</Link>
</React.Fragment>
))}
</Layout>
)
export default IndexPage
export const query = graphql`
query {
allMicrocmsBlog(sort: { fields: [createdAt], order: DESC }) {
edges {
node {
id
blogId
title
}
}
}
}
`
そして、個別の記事ページの型付け例です。こちらはGatsbyJSに新しく追加された、File System Route API
を使って動的なページを作成しています。
import React from "react"
import { graphql, Link } from "gatsby"
import { Layout } from "../../components/layout"
import { MicrocmsBlog } from "../../graphqlTypes"
type Props = {
data: {
microcmsBlog: MicrocmsBlog
}
}
const BlogPage: React.FC<Props> = ({ data: { microcmsBlog } }) => {
const blog = microcmsBlog
return <Layout>{blog.title}</Layout>
}
export default BlogPage
export const query = graphql`
query($id: String!) {
microcmsBlog(id: { eq: $id }) {
blogId
title
}
}
`
File System Route API
はこちらの記事を参考にしました。
ハマったところ
実際にGraphQL Code Generatorを導入してみて、ハマったところをご紹介します。こちらのリンクに記載されている、デフォルトの設定だとdocuments
を参照するときに以下のエラーが起きました。
→ Identifier 'getIterator' has already been declared (3329:9)
なので、下記のissuesを参考に個別にプラグインを読み込む設定にファイルを書き換えました。
documents:
- "node_modules/gatsby-source-microcms/!(node_modules)/**/*.js"
これで無事に型定義を生成することができます。
最後に
GatsbyJS + microCMS + TypeScriptの開発環境にGraphQL Code Generatorを使って型安全に開発する方法を紹介しました。型定義を自動生成することはDXに大きく繋がるので、ぜひ実践していてください。
Discussion