📌

GatsbyJS + microCMSにGraphQL Code Generatorを使って型安全な開発をする

2021/01/02に公開

こんにちはhiro08です。

もし、GatsbyJS + microCMS + TypeScriptで開発を行ってる場合、GraphQL Code Generatorを使って型安全にすることをオススメします。なぜなら、GraphQLのクエリに対する型定義は複雑で手間のかかる作業になってしまうからです。

GraphQL Code Generatorを使えば、少ない設定で型定義を自動生成してくれます。今回は型安全に開発する一例をピックアップします。
https://graphql-code-generator.com/

前提

microCMSの公式が出している、gatsby-source-microcmsを使っている前提で話を進めていきます。
https://github.com/wantainc/gatsby-source-microcms

コンテンツモデルは、endpointblogが設定されている前提を話を進めていきます。

セットアップ

まずは必要なパッケージをインストールします。

$ yarn add -D @graphql-codegen/cli @graphql-codegen/typescript @graphql-codegen/typescript-operations

そして、型定義を作成するための設定ファイルを作りましょう。codegen.ymlというファイル名にします。

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に型定義を作成するためのコマンドを追加します。

package.json
"scripts": {
  "generate": "graphql-codegen --config codegen.yml",
}

実際に開発サーバーを立ち上げてから、generateコマンドを実行すると型定義を生成してくれます。

開発サーバーを立ち上げます。

$ yarn develop

そして、開発サーバーを立ち上げた状態でgenerateします。

$ yarn generate

成功すると、srcフォルダgraphqlTypes.tsが作成されます。たったこれだけの設定で型定義を作成することができました。

生成された型定義

実際に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>;
};

こちらは生成された型定義を使うための、一覧ページの型付け例です。

index.tsx
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を使って動的なページを作成しています。

{microcmsBlog.blogId}.tsx
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はこちらの記事を参考にしました。
https://zenn.dev/ryo_kawamata/articles/gatsby-file-system-route-api

ハマったところ

実際にGraphQL Code Generatorを導入してみて、ハマったところをご紹介します。こちらのリンクに記載されている、デフォルトの設定だとdocumentsを参照するときに以下のエラーが起きました。

 → Identifier 'getIterator' has already been declared (3329:9)

なので、下記のissuesを参考に個別にプラグインを読み込む設定にファイルを書き換えました。
https://github.com/dotansimha/graphql-code-generator/issues/5024

codegen.yml
documents:
  - "node_modules/gatsby-source-microcms/!(node_modules)/**/*.js"

これで無事に型定義を生成することができます。

最後に

GatsbyJS + microCMS + TypeScriptの開発環境にGraphQL Code Generatorを使って型安全に開発する方法を紹介しました。型定義を自動生成することはDXに大きく繋がるので、ぜひ実践していてください。

参考
Gatsby × TypeScriptでGraphQL Code Generatorを使うと幸せになれる

Discussion