Ribbit's works

Gatsby-ImageからGatsby-plugin-imageへ移行した

#JavaScript #TypeScript
にメンテナンス済み
記事のトップ画像

当ブログはフレームワークとしてGatsby.jsを使用していたんですが、

OS をクリーンインストールし、環境を再構築した後からうまくビルドが通らなくなってしまいました。

Cannot read property 'bitmap' of undefined

上記のエラーが出てしまい、開発環境を localhost で立ち上げられなくなりました。

エラーメッセージに”bitmap”とあることと、スタティッククエリの画像を取得する部分を削除すれば動いたことから、画像関係で問題がでていることはわかったんですが、Github 上のいろんな issues を読み漁ってみても解決できず…

https://github.com/gatsbyjs/gatsby/issues/8301 https://github.com/gatsbyjs/gatsby/issues/12023 https://github.com/gatsbyjs/gatsby/issues/12552

幸いホスティングしているサーバー側のビルドはうまく動いていたようなので、稼働上の問題はなく、Docker を使用すれば開発環境を立ち上げることもできたのでそのまま放置。

その後しばらくしてから、gatsby-image から gatsby-plugin-image への移行が推奨されていることを知り、実際に移行してみたところビルドの問題を解決することができました。

今回はその顛末を備忘として残しておきます。

まず変更点をざっくり

React コンポーネント

このように記述していたものを、

import Img, { FluidObject } from 'gatsby-image';

...

<Img fluid={fluid} />

このように記述します。

import { GatsbyImage, IGatsbyImageData } from 'gatsby-plugin-image';

<GatsbyImage alt={alt} image={image} />;

Graphql

このように記述していたものを、

heroImage {
  fluid(maxWidth: 700) {
    ...GatsbyContentfulFluid_tracedSVG
  }
}

このように記述します。

heroImage {
  gatsbyImageData(width: 700, layout: FULL_WIDTH, placeholder: TRACED_SVG)
}

package.json の設定

今回の移行に伴い、gatsby-image を完全に使用しない形で運用が可能となるため、gatsby-image は削除して問題ありません。

代わりに gatsby-plugin-image を追加します。

npm i -D gatsby-plugin-image

npm uninstall gatsby-image

gatsby-config.js の設定

gatsby-image はコード内で直接インポートして使用していましたが、gatsby-plugin-image は gatsby-config.js へ登録が必要となります。

  ...
  `gatsby-plugin-image`,
  `gatsby-plugin-sharp`,
  `gatsby-transformer-sharp`,
  ...

スタティッククエリの削除

gatsby-image を使った運用では、フォルダ内に直接保存されているような静的なコンテンツであっても、graphql を使用して fluid もしくは fixed オブジェクトを取得する必要がありましたが、gatsby-plugin-image ではパスを指定するだけで画像データを取得することができます。

私の環境では、スタティッククエリですべてのファイルを取得するフックを用意しておいて、必要な時にそのフックを利用していましたが、その必要がなくなりました。

fluid オブジェクトについて

gatsby-plugin-image への移行に伴い、fluid オブジェクトは完全に廃止されたみたいです。

代替する方法として、前述のコードのように、graphql のオプションに(layout: FULL_WIDTH)を指定します。

graphql で指定できるオプションの一覧はこちらにあります。 Gatsby Image plugin

順次追記していきます。