💻

GatsbyJSで作っているブログでGatsby v2からGatsby v3へ移行した

2021-03-15

はじめに

2021年3月にGatsby 3.0がリリースされたので、v2からv3への移行を実施した。

v3にアップデートすると何が良くなるのか

Gatsby v3 Incremental Builds in OSS, new Gatsby Image, and more | Gatsby

大きく分けて4つある。主にパフォーマンス向上を目的とされている。

開発者向け: ローカル開発速度の80%の改善

以前は開発開始時にすべてのページや画像のビルドを待たないといけなく、ページ数や画像が多いサイトを開発していた人の辛みとなっていたが、改善された。

正直、個人のブログ程度だとあんまり辛みを感じていなかったが、記事数が増えていくと将来的に踏む可能性もあったので、アップデートしておいて損はない。1万ページのクライアントサイトというワードが出てきていたので、そういうオーダーでも耐えうるものを目指して進化していっているのだろう。大規模な開発にも耐えられるようになることは良いことだ。

コンテンツ編集者向け: あらゆるサービスでのビルド時間の短縮

Incremental Buildsによって、差分更新を実現したことによって、ビルド時間が大幅に短縮され、特にコンテンツ編集者に喜ばれていたが、Gatsby Cloud上でしか使うことができなかった。このIncremental Buildsがデフォルトで有効となり、OSSで利用できるようになったので、他のCI/CDサービスでもIncremental Buildsを活用できるようになった。

Incremental Buildsを使えるCI/CDサービスの選択肢が広がることは良いことだし、Gatsby Cloudにロックインさせようとせず、オープン化している点も良い。

サイト訪問者向け: パフォーマンスの改善

画像の最適化により、高速化を実現していたが、そのために使用していたGatsby Imageには、APIの習得が困難、Lighthouseのスコアが低く評価されはじめたという問題があり、Gatsby Imageを書き直して、新しいバージョンをリリースした。画像を表示する際のパフォーマンスが高いので、サイト訪問者にもメリットがある。

たしかに、よしなに最適化してくれるのはとてもありがたいが、APIの癖が強いと感じていたので、使いやすくしていく流れは歓迎したい。

その他

NodeやWebpackやReactなどのバージョンのアップデートも行われている。バージョンのアップデートにより、古いバージョンで遭遇するバグのリスクを減らし、Gatsby自身の機能のアップデートがしやすくなる。

古いバージョンに依存しているコミュニティプラグインが動かなくなるデメリットがあるが、メンテナンスが外れたバージョンを使用するのはセキュリティ的にもリスクがあるし、こういったアップデートをちゃんとやっていってくれるのは安心感がある。

移行の流れ

ということで、メリットも十分にあり、差分が大きくなっていくと移行が困難になるので、早めに移行しようと思い、移行を行った。移行自体は基本的に下記のガイドに書いてある通りに進めれば問題ない。破壊的変更についても言及していてくれているので、一度全体を目を通しておくと良い。

Migrating from v2 to v3 | Gatsby

遭遇する問題はそれぞれの環境次第のところが大きいと思うが、自分が対処したものが誰かの参考になればと思い、やったことを残しておく。

やったこと

Gatsbyのアップデートと依存パッケージのアップデート

ちなみに、移行する前のバージョンは 2.32.11 だった。

"gatsby": "^3.0.0" を指定して、

console
$ npm install gatsby@latest

をした。

console
$ npm outdated

を行うとアップデートすべき依存パッケージがでてくるので、それらのアップデートを行った。バージョンアップデート後、いくつか対処する必要があるものがあったので、個別で対応した。

ERROR: Using the global graphql tag for Gatsby's queries isn't supported as of v3.

Deprecated Warningが出ていたころに直した気がしていたが、一箇所だけ残っていた箇所があった。インポートするようにした。下記参照。

Using a global graphql tag for queries

Removal of sizes & resolutions for image queries

sizesを使ったままのものがあった。fluidに置き換えた。

Removal of sizes & resolutions for image queries

warn [gatsby-transformer-sharp] The "fixed" and "fluid" resolvers are now deprecated.

console
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.

ガイドに従って、 gatsby-plugin-image を使うように変更した。これが、アップデートの内容で言及していた書き直された新しいGatsby Imageだ。

Migrating from gatsby-image to gatsby-plugin-image | Gatsby

npx gatsby-codemods gatsby-plugin-image をすると自動で置き換えてくれる。

console
$ npm install gatsby-plugin-image
$ npx gatsby-codemods gatsby-plugin-image

CSS Modules are imported as ES Modules

それまで CSS Modulesを使う際にstylesでインポートしていたものを個別でインポートする必要があるので、修正した。一部、既存の変数名に被りが出たので、その辺りを調整した。少し不便だ。

CSS Modules are imported as ES Modules

Error: true is not a PostCSS plugin

console
Module build failed (from ./node_modules/postcss-loader/dist/cjs.js):
Error: true is not a PostCSS plugin
    at Processor.normalize
(.../blog/node_modules/postcss/lib/processor.es6:130:15)
    at new Processor (.../blog/node_modules/postcss/lib/processor.es6:38:25)
    at postcss (.../blog/node_modules/postcss/lib/postcss.es6:34:10)
    at Object.loader (.../blog/node_modules/postcss-loader/dist/index.js:87:20)

File: .cache/blank.css

Post CSSのバージョンを上げることで解決した。

console
$ npm install postcss@latest

ValidationError: Invalid options object. Sass Loader has been initialized using an options object that does not match the API schema.

console
Module build failed (from ./node_modules/gatsby-plugin-sass/node_modules/sass-loader/dist/cjs.js):
ValidationError: Invalid options object. Sass Loader has been initialized using an options object
that does not match the API schema.
 - options has an unknown property 'indentedSyntax'. These properties are valid:
   object { implementation?, sassOptions?, additionalData?, sourceMap?, webpackImporter? }
    at validate (.../blog/node_modules/gatsby-plugin-sass/node_modules/schema-util
s/dist/validate.js:104:11)
    at Object.loader (.../blog/node_modules/gatsby-plugin-sass/node_modules/sass-l
oader/dist/index.js:30:29)

File: src/components/amazon_link.module.sass

sass-loader のバージョンが8以降であれば指定する必要がなくなったみたいなので、

gatsby-config.js
...
{
  resolve: "gatsby-plugin-sass",
  options: {
    indentedSyntax: true,
  },
},
...

となっているオプションの指定を外した。

DeprecationWarning: OutgoingMessage.prototype._headers is deprecated

console
 ERROR

(node:6033) [DEP0066] DeprecationWarning: OutgoingMessage.prototype._headers is deprecated

一文しか出ていので、原因を調査するために、

console
$ node —trace-deprecation node_modules/gatsby/dist/bin/gatsby develop

をしたところ、

console
 ERROR

(node:7710) [DEP0066] DeprecationWarning: OutgoingMessage.prototype._headers is deprecated
    at module.exports (.../blog/node_modules/timed-out/index.js:9:17)
    at EventEmitter.<anonymous> (.../blog/node_modules/got/index.js:244:5)
    at Object.onceWrapper (events.js:422:26)
    at EventEmitter.emit (events.js:315:20)
    at makeRequest (.../blog/node_modules/cacheable-request/src/index.js:94:9)
    at .../blog/node_modules/cacheable-request/src/index.js:104:14
    at runNextTicks (internal/process/task_queues.js:62:5)
    at processImmediate (internal/timers.js:429:9)

と返ってきたので、gotのバージョンを上げることで解決した。

console
$ npm install got@latest

どうやら、 gatsby-source-filesystem では対応済みのようだが、他のパッケージが古いバージョンに依存していたようだ。

[gatsby-source-filesystem] Deprecation warning · Issue #18433 · gatsbyjs/gatsby

warn chunk commons [mini-css-extract-plugin] Conflicting order. Following module has been added:

このWarningだけ解消しきれなかった。

mini-css-extract-plugin Conflicting order warning in gatsby v3 · Issue #30168 · gatsbyjs/gatsby

上記Issueが立っていて、下記Discussionに移行されていたが、まだ議論は進んでいないようだった。

mini-css-extract-plugin Conflicting order warning in gatsby v3 · Discussion #30169 · gatsbyjs/gatsby

議論が進むのを待ちつつ、Warningだし、様子をみることとした。

gatsby develop が通るようになる

gatsby develop が通るようになったので、ローカルで動作確認をして問題がないことを確認した。PRを作成し、CI上でbuildが成功していることを確認し、previewで動作確認を行った。

おわりに

色々と遭遇したが、無事にアップデートを終えることができて良かった。Dependabotで日々パッケージのアップデートを行ったり、Deprecated Warningに対応していたので、スムーズに対応できたように思える。やはり破壊的変更が入るメジャーアップデートの際は差分が少ないほど良い。個人開発でもDependabotを入れておくとバージョンアップデートのハードルが下がるので、入れてない人にはおすすめしたい。引き続きメンテナンスしていきつつ、最新のアップデートを享受していきたい。

キクナントカ

キクナントカ

ソフトウェアエンジニアをしています。Flutter、Rails、GatsbyJSを主に触っています。趣味でボードゲームを制作したり、個人開発したりしています。詳しくはこちら