😺

今更Gatsby入門

2023/07/11に公開

ちょっと今更感はありますが、初めてGatsbyを使ったので備忘録。ポートフォリオを作りました。詳細な手順等は公式に譲るとして、初めて触って気になった点を広く浅くざっくりまとめます。

実施環境
項目 詳細
PC MacBook Pro(14 インチ、2021)Apple M1 Pro
OS MacOS Ventura 13.4
Node v18.16.0
Gatsby v5.9.0
React v18.2.0

Gatsbyとは

当初はReactベースのオープンソースSSG(静的サイトジェネレータ)フレームワークでしたが、今ではSSGに加え、SSR、そしてDSGというのもできるようです。すごく大まかなくくりで見たときの機能としてはNext.jsとほぼ変わらない印象です。GraphQLとの連携が強い様子。また、最近Netlifyに買収されました。

SSR/SSG

SSRとSSG(Static Site Generator)

こちらの記事がわかりやすかったので引用させていただきます。

SSR
SSRはざっくり、ページ遷移のたびサーバーにリクエストが走り、そのままサーバー側でAPIと連携をしてレンダリングが行われ、生成されたHTMLをブラウザに返すアーキテクチャのことをいいます。

SSG
SSGはざっくり、ビルド時に、サーバー側で、APIからのデータ取得とそれに伴ったHTMLの構築を終わらせておき、ユーザーからリクエストされた際にこの事前につくっておいたHTMLを渡すアーキテクチャです。

DSG(Deferred Static Generation)

恥ずかしながら初めて聞きましたが、Gatsbyの独自機能で、公式によるとビルド時に生成するページとユーザリクエスト時に生成するものを分けられる機能のようです。non-critical でアクセス数も少ないのにビルドの負担になっているものはリクエスト時に生成することで、ビルド時間を短縮するのが狙いの様子。勝手にISR的なものかと想像してましたがだいぶ違いました。

vs Next.js

Google Trendsで見た限りでは、2020年頃までは競っていたものの、近年ではNext.js一強状態のように見えます。海外であれば2023年の比較記事がまだいくつかあるのですが、日本の記事は新しいものがあまりヒットしません。SSGならGatsby、SSRならNext.jsという棲み分けがされていたのが、Next.js側がSSGを実装したことで公式っぽいしNext.jsでいいじゃんっていう流れになっちゃったんですかね…?

とは言えGraphQLへの親和性やプラグインエコシステムが充実しているなどの強みはあるようです。Gatsby触る前時点での印象としては、汎用性高くちゃんと作り込むならNext.js、テンプレートやプラグインを使ってサクッと高速なサイトを作るならGatsbyといった印象を受けました。

Hello World

ドキュメントがどこにあるか若干わかりにくい…が、ここ。プログラミング初心者向けのTutorialからやってみましたが、とても丁寧に解説されておりわかりやすかったです。(経験者からすると多少冗長な部分もあるかと思いますので、すぐ始めたいという人用にはQuick Startもあります。)

まずは Gatsby CLI をグローバルにインストール。その後newコマンドで対話形式での初期設定を行います。いくつかの質問に答えれば初期設定が完了します。

// cliインストール
npm install -g gatsby-cli

// プロジェクト作成スタート
gatsby new

// フォルダに移動して下記コマンドで起動
npm run develop

プラグイン

tutorialでも章が別れていたので、推している機能だと思われます。

a plugin is a separate npm package that you install to add extra features to your site.

とのことなので、要はnpmパッケージだと思うのですが、Gatsby専用でエコシステムができあがっているというところが推しポイント?

GraphQL

GraphQLとの連携はかなり力を入れている印象を受けました。サイト内データや外部データなどをsource pluginというものを通じてData Layerにまとめ、useStaticQueryフックでGraphQLクエリを発行して取得するという仕組みがデフォルトで出来上がっています。型もこちらの設定をすれば自動で付きます。

source plugin

何かしらのデータをData Layerにつなぐためのプラグイン群です。データの取得先ごとにプラグインが用意されています。
例えばプロジェクト内にblogフォルダを作り、gatsby-source-filesystem(ファイル用のsource plugin)を入れて(npm install gatsby-source-filesystem)設定をすることでblogフォルダをData Layerに接続することができます。

gatsby-config.js
  plugins: [
  ...
    {
      resolve: "gatsby-source-filesystem",
      options: {
        name: `blog`,
        path: `${__dirname}/blog`,
      }
    },
   ...

これに対してuseStaticQueryフック経由でGraphQLのクエリを発行すればファイルの名前などを取得できます。

layout.js
  const data = useStaticQuery(graphql`
    query {
      site {
        siteMetadata {
          title
        }
      }
    }
  `)
  
  ...
  
  <header className={siteTitle}>{data.site.siteMetadata.title}</header>

source pluginは様々な種類が用意されており、各種CMSやDBなどにも接続できます。これはかなり便利な気がする。(が、ページコンポーネントとその他のコンポーネントで書き方が違うぽくちょっとめんどう。)

transformer plugin

上記の例で、gatsby-source-filesystemだけではファイルの中身はとってこれないようで、gatsby-source-filesystemで取得したデータを変換する別プラグインが必要とのこと。そういったプラグインをtransformer pluginと言うらしいです。

GraphiQL

GraphQLではなくGraph i QLです。Data Layerに発行するクエリを試すためのブラウザツールで、npm run developしたときに同時に起動されます。http://localhost:8000/___graphqlでアクセスでき、簡単にクエリを試したりすることができます。ここで試したクエリをプロジェクトコードに貼り付けて使うというのが大まかな流れのようです。

File System Route API

例えばブログの記事詳細ページなど、同じフォーマットでデータだけが変わるようなページに使用するAPIです。

{nodeType.field}.jsという書式でファイルを作成すると、Data Layer上のNodeという単位でビルド時にページを作成してくれるようです。例えば、src/pages/blog/{mdx.frontmatter__slug}.jsというファイルを作ったとすると、mdxのノード数分ページを作成し、URLはfrontmatterのslugというフィールドの値が使用されます。

CSS

今回Tailwind使おうかと思っていたのに、gatsby newした際に選択肢になかったのでアレ?と思ったのですが(v5.9.0時点)、公式のガイドがありました(かつ、下にも載せてますが、v5.11.0に上げると初期選択時にTailwind追加されていました。)。TailwindCSS側のサイトに導入手順が載っていたのでそれに従って導入。GatsbyとしてはCSSは特に縛りはないようです(チュートリアルはCSS modulesでした。設定不要。)。

v5.11.0時点でgatsby newのときに選べるものは以下でした。

  • Emotion
  • PostCSS
  • Sass
  • styled-components
  • Theme UI
  • vanilla-extract
  • Tailwind CSS

linter

ESLint

公式ではビルトインで組み込まれているとのことだったが効いてなさそうだったので(私がなにか勘違いしてそう)、こちらに従って設定したら効きました。

Prettier

公式の記載がなさそう…?こちらを参考にしつつ導入。

多言語化

こちらのプラグインを入れておくとよさそうでした。
https://github.com/microapps/gatsby-plugin-react-i18next

公式には使用する文言自体をキーにする方法("はじめまして"なら"はじめまして": "はじめまして""はじめまして": "nice to meet you"をデータとして記載しておいて、実際のページでは<Trans>はじめまして</Trans>のように記述すると出し分けてくれるイメージ。)で書かれていたのでそうしました(ただ、文言変わったときに変える箇所多くて良し悪しだなとは思いました。greetingとかのキーを当ててもいいとは思います。)。

出し分けのためには各ページで下記クエリを発行する必要があるようです(共通化できるのかはちょっと調べてないです)。

export const query = graphql`
  query ($language: String!) {
    locales: allLocale(filter: { language: { eq: $language } }) {
      edges {
        node {
          ns
          data
          language
        }
      }
    }
  }
`;

画像の表示

画像の表示はちょっとひとクセあるなという印象でした。こちらの記事がわかりやすかったので載せておきます。この中のGatsby-imageプラグインを使った方法を採用しています。

デプロイ

Gatsbyクラウド?というのがあって、Githubのリポジトリからそのままデプロイできます。設定はこのあたりを参考に進めるとすぐできました。便利。

その他の特徴

  • Next.jsと同じく、pagesフォルダ配下のフォルダ/ファイル構造がそのままURL構造になる
  • Next.jsのLinkとほぼ同じと思われる内部リンク用Linkコンポーネントが存在。
    • リンクがビューに入ったときやホバーしたときにpreloadingしてくれるとのこと
    • 外部リンクは<a>タグを使用する
  • Gatsbyで用意されたHeadコンポーネントにmeta情報を記述できる
  • 開発用ビルド時に404ページを表示すると、ビルドされたRouteの一覧が見れる

  • import時にエイリアス(import '@components/navbar')を効かせるプラグインがある。(tsconfigのbaseUrlとpathをいじればエディタ上でのエラーは消えるが、ビルドできなかった。)
  • 環境変数はこちらを参考に設定
  • Google Analyticsはこちらのプラグインを入れてgatsby-configにもろもろ記載するだけで設定可能

まとめ

Gatsby触る前時点での印象としては、汎用性高くちゃんと作り込むならNext.js、テンプレートやプラグインを使ってサクッと高速なサイトを作るならGatsbyといった印象を受けました。

触る前上記イメージでしたが、使ってみたあともあまりイメージ変わりませんでした。更に各種starterも用意されているので、テンプレに乗っかればかなり高速に開発できそうだなと。追加でなにかやりたいなと思ったときには大抵プラグインがあるので、とりあえず入れておけば動くし、最適化された状態で使えます。初めての方でもかなり開発しやすいのではと感じました。

反面、Gatsbyに限らずテンプレ/ボイラープレートは高速に標準化されたものを作りやすいものの、そこから少しそれると途端に難しくなってしまうものかなと思います。面倒事をブラックボックス化して楽させてくれるものなので、ブラックボックスを開けなければならない事態になれば大変なのはそうで、結局要件と相談にはなるのかなと。特殊な要件のない、標準に寄せられそうなサイトとかだと向いているかなと思いました。(対してNext.jsはもうちょっと低レベルの機能をたくさん提供して、あとは好きにやってーっていうイメージ?)

人気が落ちている?中でどこまでエコシステムがメンテされていくのかが気になるところですが、個人的には全部DataLayerに突っ込んで使うとことかプラグインエコシステムとか面白いなと思ったので、またいつか触ってみたいなと思います。

Discussion