GatsbyJS を4から5にアップデートしてみる

GatsbyJS を4から5にアップデートしてみる

目次

warn Browserslist が…

いつからか、以下の様なものが表示される様になっていました。

warn Browserslist: caniuse-lite is outdated. Please run:
  npx browserslist@latest --update-db
  Why you should do it regularly: https://github.com/browserslist/browserslist#browsers-data-updating

とりあえず、ググってみる。

ターミナル上に記載されていた github へのリンクや上記記事を読んだ後、Please run に書かれているコマンドを走らせてみると、先の warn は表示されなくなりました。

4 の最新版にアップデートしてみたら…

GatsbyJS が 5 になっているみたいなので、アップデートしようかな? と。

Before upgrading to v5 we highly recommend upgrading gatsby (and all plugins) to the latest v4 version.

まずは 4 の最新版(プラグインとかも)にアップデートしてからにしてね的なことが書かれていたので、その通りにやってみる。

4 の最新版(4.25.0)にしてから gatsby develop すると、今度は以下の warn が出る様になりました。

warn gatsby-plugin-react-helmet: Gatsby now has built-in support for modifying the document head. Learn more at https://gatsby.dev/gatsby-head

リンク先を見てみると、4.19.0 から react-helmet ではなく、Gatsby Head API が使われる様になったと。

上記記事などを参考にし、react-helmet を Gatsby Head API に置き換えました。(Gatsby の Tutorial も、Gatsby Head API を使ったものに更新されていますね!)

5 にアップデートしてみる。

4 の最新版にアップデート出来たので、次に 5 にアップデートしてみる。

For most users we expect a smooth upgrade path as only a couple of changes will be required: Updating to Node 18, switching to React 18, and changing GraphQL queries using a codemod.

5 を動かすには、React も node も v18 以降にし、プラグインも最新バージョンに置き換えました。

npx gatsby-codemods@latest sort-and-aggr-graphql .

GraphQL の書き方が変更になっているみたいなので、マニュアルにもある様に上記のコマンドを叩いて変換してから、gatsby develop をしてみたら…

色々とエラーが出た!

4 の時は、slug を取得出来ていた…

pages/index.js ファイルに、以下の様なエラーが出ていました。

ERROR #85923  GRAPHQL.VALIDATION

There was an error in your GraphQL query:

Cannot query field "slug" on type "Mdx".

Gatsby4 の時は、以下の様な記述で slug (ブログ記事のフォルダ名)を取得し、それを個別記事へのパスとして使っていました。

query MyQuery {
  allMdx {
    edges {
      node {
        frontmatter {
          title
          tags
        }
        slug
      }
    }
  }
}

これを GraphiQL で実行すると、

{
  "data": {
    "allMdx": {
      "edges": [
        {
          "node": {
            "frontmatter": {
              "title": "TailWindCSSのlast、@apply、last-of-typeを使ってみる",
              "tags": ["TailWindCSS"]
            },
            "slug": "tailwindcss-apply-last-type-of/"
          }
        },
        {
          "node": {
            "frontmatter": {
              "title": "Gatsbyの記事に目次を作成してみる",
              "tags": ["GatsbyJS"]
            },
            "slug": "table-of-contents/"
          }
        }
      ]
    }
  },
  "extensions": {}
}

こんな感じで、slug を取得出来ていましたが、(GraphiQL を見てみると)5 からは、slug の項目がなくなっている…

最新(v5)のチュートリアルにもある様に、mdx ファイル側で slug を設定してあげて、

---
title: "TailWindCSSのlast、@apply、last-of-typeを使ってみる"
tags: ["TailWindCSS"]
slug: "tailwindcss-apply-last-type-of"
---

それを graphql で取得する様に変更しました。(4 の時からこの手法を取っていた方は、修正しなくても大丈夫かと)

export const query = graphql`
  {
    allMdx(sort: { frontmatter: { date: DESC } }) {
      nodes {
        frontmatter {
          title
          tags
          slug
        }
      }
    }
  }
`

templates のファイルにも…

templates フォルダ内に作成したファイルにも、先と同様のエラーが出ていたので、そちらも修正。

加えて propTypes も修正する。以前はこんな感じ。

Tags.propTypes = {
  pageContext: PropTypes.shape({
    tag: PropTypes.string.isRequired,
  }),
  data: PropTypes.shape({
    allMdx: PropTypes.shape({
      totalCount: PropTypes.number.isRequired,
      edges: PropTypes.arrayOf(
        PropTypes.shape({
          node: PropTypes.shape({
            frontmatter: PropTypes.shape({
              title: PropTypes.string.isRequired,
            }),
            slug: PropTypes.string.isRequired,
          }),
        }).isRequired
      ),
    }),
  }),
}

slug の記述箇所を、修正しました。

Tags.propTypes = {
  pageContext: PropTypes.shape({
    tag: PropTypes.string.isRequired,
  }),
  data: PropTypes.shape({
    allMdx: PropTypes.shape({
      totalCount: PropTypes.number.isRequired,
      edges: PropTypes.arrayOf(
        PropTypes.shape({
          node: PropTypes.shape({
            frontmatter: PropTypes.shape({
              title: PropTypes.string.isRequired,
              slug: PropTypes.string.isRequired,
            }),
          }),
        }).isRequired
      ),
    }),
  }),
}

動的に作成する個別記事ページも…

記事一覧ページから個別記事ページに遷移しようとしたら、動的にページが作成されずにエラーとなる現象も出ました。

ファイル名を変更

バージョン 4 の時は{mdx.slug}.js だったファイル名を、チュートリアルにもある様に、{mdx.frontmatter__slug}.js に変更。

データ取得の記述も修正

4 の時は以下の様な記述でデータを取得していました。(v4 のチュートリアルも、この方法だった様な気がする)

import { MDXRenderer } from "gatsby-plugin-mdx"

(略)

<MDXRenderer>{data.mdx.body}</MDXRenderer>

う〜ん、何が問題なのかなぁ… そういえば v5 のチュートリアルで MDXRenderer って出てきたっけ?

MDXRenderer は、使ってない!

page-templates の変更点みたいな記事もあったので、そちらを見ても MDXRenderer は使わず、children を使っていました。

const BlogPost = ({ data, children }) => {
(略)
<article>
        <h1>{data.mdx.frontmatter.title}</h1>
        (略)
        {children}
</article>

この様にコードを修正するとエラーにならず、個別記事のページに遷移出来る様になりました。