Gatsby v2からGatsby v3への移行

2021年3月21日 2023年12月11日

本ブログはGatsby v2で作成されていましたが、2021年3月にGatsby v3が公開されましたので、移行しました。 この記事では、その際にいくつか手間どったこともあったので、誰かの参考になればと思い、その対応についてまとめています。

Gatsby v3へ移行する理由

Introducing Gatsby 3.0 – Faster in Every Way that Mattersに詳細が記載されていますが、端的に言うと、すべてのユーザ(開発者・記事編集者、訪問者)にとって高速化されています。 また、Gatsbyに関連するプロジェクトのバージョンアップも行われ、古いバージョンのバグにも遭遇しづらくなっています。

一番の理由は、おもしろそうなので、とりあえずやってみます!

移行手順

公式の移行ガイドがありますので、基本的にはそれに従います。

Gatsby本体の更新

package.json内のgatsbyのバージョンを以下のように編集します。

package.json
{
  "dependencies": {
    "gatsby": "^3.0.0"
  }
}

その後、以下のコマンドを実行して、Gatsby自体を最新にします。

Terminal
npm install gatsby@latest --legacy-peer-deps

なお、私はnpm 7以上を利用しているので、--gegacy-peer-depsオプションを付加しています。 このオプションが無いと、依存関係の問題で以下のエラーが発生します。

Terminal
npm ERR! ERESOLVE unable to resolve dependency tree

関連パッケージの更新

以下のコマンドでインストールされているパッケージの最新バージョンの有無を確認します。

Terminal
npm outdated

公式の手順では上記コマンドで表示されたパッケージを一つずつ更新していますが、更新対象パッケージが多く手間なので、npm-check-updatesを利用します。 npm-check-updatesはpackage.jsonの依存関係を最新バージョンにアップグレードしてくれるパッケージです。

Terminal
# npm-check-updatesをglobalにインストール
npm install -g npm-check-updates

# 更新対象パッケージの表示
ncu

# packege.jsonの更新
ncu -u

上記手順でpackage.jsonが更新されましたので、以下のコマンドで実際にパッケージを更新しています。

Terminal
npm update --legacy-peer-deps

ここでも--gegacy-peer-depsオプションを付加しています。

上記オプションで依存関係を無視してバージョンをあげているので、Gatsby v3に対応していないパッケージもあります。 しかし、公式の手順に「対応していないパッケージでもほとんどの場合、上手く動作する」旨の記載がありますので、今回気にせず進めました。 私は一つだけ対応していないパッケージがありましたが、問題なく動作しました。

ここまでで、Gatsby v3へのバージョンアップ自体は完了です。

各種警告及びエラー対応

さっそくキャッシュをクリアして、Gatsbyをdevelopment環境で起動しましたが、警告とエラーで正常に起動しません。 Gatsby v2からGatsy v3に変わったことで、記法や読み込み方法が変わっています。

ここからは、私の環境で出現した警告・エラーを元に対応していきます。

imageクエリからsizeの削除

以下のエラーが発生しました。

Terminal
The fragment "GatsbyImageSharpSizes" does not exist.

Removal of sizes & resolutions for image queriesに記載があるようにsizeはGatsby v3では利用できませんので、fluidに変更します。

gatsby-plugin-imageへの移行

以下の警告が発生しました。

Terminal
warn [gatsby-transformer-sharp] The "fixed" and "fluid" resolvers are now deprecated. Switch
 to "gatsby-plugin-image" for better performance and a simpler API. See
https://gatsby.dev/migrate-images to learn how.

先ほどsizeからfluidに移行しましたが、そもそもfluidもfixedとともに非推奨のようです。 推奨されているgatsby-plugin-imageに公式手順に従って移行します。

まず、関連するプラグインのインストールします。

npm install gatsby-plugin-image gatsby-plugin-sharp gatsby-transformer-sharp

次にgatsby-config.jsに以下を追記してプラグインを有効化します。

gatsby-config.js
module.exports = {
  plugins: [
    `gatsby-plugin-image`,
    `gatsby-plugin-sharp`,
    `gatsby-transformer-sharp`,
  ],
}

さらに、以下のコマンドを実行して、該当のGraphQLをgatsby-plugin-image用に自動で修正します。

Terminal
npx gatsby-codemods gatsby-plugin-image

あとは、画像を読み込んでいる箇所でGatsbyImageやStaticImageを使って画像を表示するように変更します。

CSS Modulesのインポート方法変更

CSS Modules are imported as ES Modulesに記載されているように、Css ModulesがES Modulesとして読み込まれるように変更されました。

import React from "react"
- import styles from './mystyles.module.css'
+ import { box } from './mystyles.module.css'

const Box = ({ children }) => (
-  <div className={styles.box}>{children}</div>
+  <div className={box}>{children}</div>
)

export default Box

上記の変更でツリーシェイク機能が使えるようになったとのことです。

しかし、今までstylesで読み込んできたので、変更箇所が膨大です。 ツリーシェイクが使えなくなるので推奨はされていませんが、以下のように記載すると従来と同様にstylesが利用できます。

- import styles from './mystyles.module.css'
+ import * as styles from './mystyles.module.css'

しかし、上記のように修正しても対応しきれない点があります。それはCss ModulesがES Modulesとして読み込まれるようになったため、cssに記載しているクラス名が、jsxファイルから参照する際に以下のようにcamelCaseに自動変換されてしまいます。

# cssで .title-nameで指定している場合、jsxではtitleNameでアクセスする必要がある

- <div classNmae={styles['title-name']}/>test</div>
+ <div classNmae={styles['titleName']}/>test</div>

自動でcamelCaseに変換しないようにしたかったのですが、抑止方法が分からず、すべてcamelCaseに修正しました… (Css modulesから styled-componentsに移行すべきか…)

本番環境での画像サイズの制御

ローカルのdevelopment環境では、警告・エラーがなくなりましたが、netlifyにdeployしたら、一覧画面に表示されるアイキャッチ画像のサイズがバラバラになってしまいました。

本ブログでは、レスポンシブ対応として、imgタグでディスプレイサイズによって画像サイズを指定していましたが、どうやらその指定が有効になっていないようです(development環境では問題ありませんでした)。

調査してみると、本番環境だと、「.gatsby-image-wrapper」クラスが画像に適用されて画像の本来のサイズがそのまま表示されるようになっています。

GraphQLで画像を取得する際に表示したいサイズで取得できますが、レスポンシブ対応のため、どうにかしてcssでサイズを指定したいです。

Gatsby Image pluginによると、GatsbyImageの属性値としてclassNameを利用すると、wrapperに適用するcssを定義できるようなので、新たに画像サイズを制御する用のクラスをつくって対応しました。

<GatsbyImage
  className={styles['imgSize']}
  image={featuredImage.childImageSharp.gatsbyImageData}
  alt={post.frontmatter.title}
/>

終わりに

なんとかGatsby v3への移行が完了しました。 メジャーバージョンが変更になったわりには変更対応が必要な箇所が少なくて良かったです。

ここまで読んでいただき、ありがとうございました。 少しでもどなたかの参考になれば嬉しいです。

Posted by mako
コメント
...