個人ブログで使っているGatsbyのバージョンを4系から5系にあげた
はじめに
寝ようとしていたところ、Gatsbyでバージョン5がリリースされていたのを知った。気になったので寝る前に対応することにした。
主な変更点は以下のようだ。
- SliceAPIの導入
- PartialHydrationの導入(Beta)
- GraphiQLのバージョン2系へのアップデート
- Node18の利用
- React18の利用
これに伴ってNode14と16や、React16と17のサポートを切るようなので遠からぬうちにGatsbyのバージョンを上げておいたほうが良いだろう。
他にもgatsby-configとgatsby-nodeをTypeScriptで書けるようになったりと嬉しい変更もあるようだ。詳しくは公式のリリースノートを参照されたい。
さて、今回は個人ブログで使っているGatsbyのバージョンを5系に上げる際にやったことと遭遇したエラーについてまとめておく。
進め方
Gatsbyの5系には破壊的変更が加えられているので、公式の方でマイグレーションガイドを用意してくれている。基本的にはこれに沿って進めれば良いと思われる。
やったこと
以下に自分が対応したことを挙げておくが、環境ごと追加の対応も必要になると思われるので公式のマイグレーションガイドを一読しておくことを勧めたい。
Gatsbyのバージョンを上げる
とりあえず現時点で最新のバージョンである5.0.1にバージョンを上げた。
{
"dependencies": {
"gatsby": "^5.0.1"
}
}
Reactのバージョンを上げる
といっても自分の場合は最初からReactを最新版にしていたので何もしなかった。上げていない場合はアップデートしておこう。
{
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
}
}
gatsby-pluginのバージョンを上げる
gatsby-source-filesystemやgatsby-plugin-imageといった、頭にgatsby-*とついているパッケージをひたすら最新版に上げた。
GraphQLの書き方を変えた
Gatsby内部で使っているGraphQLのアップデートもしたようで、sortと集計用のfields引数の書き方が変わったようだ。
# Before
allMarkdownRemark(sort: { fields: [frontmatter___date], order: DESC })
# After
allMarkdownRemark(sort: { frontmatter: { date: DESC } })
# Before
allMarkdownRemark {
distinct(field: frontmatter___category)
}
# After
allMarkdownRemark {
distinct(field: { frontmatter: { category: SELECT } })
}
これについてはマイグレーション用のcodemodツールが用意されているようで、以下のコマンドを打つことで移行が完了できた。
npx gatsby-codemods@latest sort-and-aggr-graphql .
trailingSlashをneverに設定
trailingSlashはURLの最後に/をつけるかどうかのオプションだ。
Gatsby4ではデフォルでlegacyだったが、これが削除されて5系ではデフォルトがalwaysとなった。
個人的には付けたくないのでneverを設定するようにした。これは個人の好みの問題なので必ず設定する必要のあるものではない。
// gatsby-config.js
module.exports = {
trailingSlash: `never`,
}
出てきたエラーと対処法
以上が自分が今回対応したものになるが、人によっては追加の設定が必要になると思われるので詳しくは公式のマイグレーションガイドを参照されたい。
次に今回の移行に際して詰まったところを挙げておく。
上記の対応が終わってビルドしようとしたところ、以下のエラーが出てきた。
Missing onError handler for invocation 'building-schema', error was 'Error: Cannot
create as TypeComposer the following value:
GraphQLScalarType({ name: "Date", description: "A date string, such as 2007-12-03,
compliant with the ISO 8601 standard for representation of dates and times using the
Gregorian calendar.", specifiedByURL: undefined, serialize: [function String],
parseValue: [function String], parseLiteral: [function parseLiteral], extensions: { },
astNode: undefined, extensionASTNodes: [] }).'.
これは公式のガイドでも既知の問題として挙げられており、依存パッケージが複数のバージョンのgraphqlパッケージに依存していることが問題なようだ。
以下のコマンドで現状のgraphqlへの依存バージョンを確認できる。
# npm
npm ls graphql
# yarn
yarn why graphql
公式で挙げられている対処法としては、lockファイルとnode_modulesを削除し、npm install --legacy-peer-deps/yarn installで再度パッケージをインストールする方法を紹介している。
複雑な設定をしているプロジェクトにおいてはresolutionsのような機能を使う必要があるようだが、自分のブログはシンプルなのでこの対応に従った。
この対応によってビルドが行けそうに思えたが、以下のエラーが出るようになった。
Cannot find module 'graphql'
node_modulesを見てもgraphqlが入っていたので理由は分からなかった。原因はよく分からなかったが、Gatsbyは今回からgraphqlのv16を内部的に使うようにしたといっているので、package.jsonに明示的にgraphqlをインストールするようにした。
{
"dependencies": {
"graphql": "^16.6.0"
}
}
これでnpm installをすると先ほどのエラーは消え、ビルドが無事に成功するようになった。
おわり
実際に開発環境で動かしてみると動作も表示も問題なさそうだったので本番環境の方にデプロイした。
最後にエラーにはぶつかったものの公式の方で既知の問題として紹介されていてすぐ解決できたし、必要な対応は公式のマイグレーションガイドに記載されていたので対応もスムーズに進めることができた。
公式の詳細なドキュメントは本当にありがたい…