ブログを GatsbyV3 へ移行した

このブログを先日リリースされた Gatsby V3 に移行しました!

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

大きく挙げられているのは

  • 開発サーバーの高速化
  • ビルド高速化
  • gatsby-plugin-image へのリプレイスによる Lighthouse スコアの向上

の 3 つでした

移行する

Migrating from v2 to v3 | Gatsby

こちらの公式のガイドに従う形で v3 へ対応しました

後述する gatsby-plugin-image と CSS Modules 以外は特にコードを書き換える必要はなく、パッケージのバージョンをあげるだけで済みました

gatsby-plugin-image への移行

gatsby-plugin-image への移行にもガイドが用意されていたので、これに従います(ありがたや…)

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

$ yarn add -D gatsby-plugin-image
module.exports = {
  plugins: [
    `gatsby-plugin-image`,
    `gatsby-plugin-sharp`,
    `gatsby-transformer-sharp`,
  ],
}

しつつ、既存の gatsby-image コンポーネントを置き換えていきます

gatsby-plugin-image では、StaticImageGatsbyImage の 2 種類のコンポーネントが用意されていて、動的にクエリから取得する必要がある画像(投稿と紐付いたサムネイルとか)はこれまで通り、特定の画像ファイル(サイトロゴとか)はクエリを介さずに直接 StaticImage で使用できます

import { StaticImage } from "gatsby-plugin-image"

<StaticImage
  src="./logo.png"
  alt="alt here"
  layout="fixed"
  height={90}
  width={120}
/>

fluid を使っていたところは、layout="fullWidth" 使えば良さそうです

画像周りのクエリの API も変更されています

childImageSharp {
  gatsbyImageData(
    layout: FULL_WIDTH
    formats: [AUTO, WEBP, AVIF]
    placeholder: TRACED_SVG
  )
}
import { GatsbyImage } from "gatsby-plugin-image"

const image = data.hoge.childImageSharp.gatsbyImageData

<GatsbyImage
  image={image}
  alt="alt here"
/>

以前よりわかりやすいですね

CSS Modules の移行

Migrating from v2 to v3 # CSS Modules are imported as ES Modules | Gatsby

にあるように、CSS Modules は ES Modules で読み込むようになったそうです(てことはもともと commonjs だった?)

The web moves forward and so do we. ES Modules allow us to better treeshake and generate smaller files. From now on you’ll need to import cssModules as: import { box } from ‘./mystyles.module.css’

ツリーシェーキングの為だそうで、たしかに合理的っすね

- import styles from "./example.module.css"
+ import { example } from "./example.module.css"

差分としてはこんな感じです

ただ少なくともこのブログでは、各ファイルのセレクタが多くないので抜けはほぼないからツリーシェーキング云々はそこまで影響ないだろうかなってのと、型定義が楽なので import * as styles from "./example.module.css" で読むようにしました

型定義は、デフォルトエクスポートがネームドエクスポートに変わったので

declare module "*.module.css" {
  const styles: {
    [key: string]: string
  }
+  export = styles
-  export default styles
}

こんな感じで型定義を変更しました

SCSS の Css Modules が使えない

SCSS だと CSS Modules が読み込めなくなっていて、gatsby-plugin-sass が追従できてないのかなーと思ったんですけど、公式の example に v3 対応版があがっていたので大丈夫そう

gatsby-plugin-sass の実装を読んでみたら、分岐で CSS Modules が有効化されてないパターンがあるみたいでした

とりあえずの対応としては、

{
  resolve: `gatsby-plugin-sass`,
  options: {
    implementation: require(`sass`),
    sassRuleTest: /\.scss$/,
    sassRuleModulesTest: /\.module\.scss$/,
+    cssLoaderOptions: {
+      modules: true,
+    },
    ...
  },
},

cssLoaderOptions で明示的に有効化してやって対応しました

あとで、少し試してプルリクを出しておこうと思います

追記: v4.0.2 で修正されてました

パフォーマンス

さっそくデプロイしてみました (v3, v2)

指標差分
Transfer415.9 KiB → 354.2 KiB
デスクトップ向け Lighthouse パフォーマンス95 → 99
モバイル向け Lighthouse パフォーマンス75 → 78

FCP と TTI はほぼ変わらず(というかもともと高速)ですが、LCP と TBT が結構改善してるっぽいです

せっかく Gatsby 使ってるからには速くしておきたいので結構うれしみです

開発サーバーのほうは確かに速くなってるんですけど、(少なくとも僕の環境では)ホットリロードが回らなかったりしてて体験が微妙でした