Gatsbyのthemeを作成して公開しました


React をベースにしたフレームワークの Gatsby。表示が早く SEO フレンドリー、ホスティングサービスとの連携も取りやすいと至れり尽くせりです。アップデートが早く、採用されている技術も面白く勉強になります。

Gatsby を使った開発ではスターターテンプレートを使うのが一般的です。create-react-app のように hello wolrd なものから、実用的な web サイトっぽいものなど色々と用意されています。

スターターテンプレートは便利ですが、テンプレート自体のコードと、自身開発時のコードが分離されるようには出来ていません。なので、使用しているスターターテンプレートが機能追加や不具合修正で更新されていっても、その更新をプロジェクトに取り込むのは難しいです。

Theme は正式にリリースされました

2019 年 7 月に theme は experimental から stable に代わり、正式に gatsby の API として提供されました。

Gatsby Themes の安定版リリースされたので gatsby-crudzoo もアップデートしました

この記事の内容は、theme を実験的と表現している以外は特に問題ありません。

実験的な機能としてのテーマ

Gatsby Themes

Gatsby には スターターテンプレートとは別に theme という機能が実験的に実装されています。これはスターターテンプレートとは違い、ライブラリとしてテンプレートを使用することができます。

スターターテンプレートでは、package.json にスターターテンプレート用の構成があり、gatsby-config.js といった様々な設定ファイルが初期状態で存在します

"dependencies": {
    "gatsby": "^2.8.2",
    "gatsby-image": "^2.1.2",
    "gatsby-plugin-feed": "^2.2.2",
    "gatsby-plugin-google-analytics": "^2.0.20",
    "gatsby-plugin-manifest": "^2.1.1",
    "gatsby-plugin-offline": "^2.1.1",
    "gatsby-plugin-react-helmet": "^3.0.12",
    "gatsby-plugin-sharp": "^2.1.3",

    ...省略

テンプレートをベースにして自身の開発を加えていきます。theme だとライブラリになるので

  "dependencies": {
    "gatsby": "^2.7.1",
    "react": "^16.8.6",
    "react-dom": "^16.8.6",
    "gatsby-crudzoo": "0.0.2" // オリジナルのテーマ
  },

自身のカスタマイズとは独立して扱うことができ、必要な依存関係や設定ファイルはライブラリ内に入ります。使用している theme がバージョンアップされたら、通常のライブラリと同様にアップデート可能です。

自身サイト用の theme を作ってみた

このサイトはもともと gatsby-starter-blog をスターターテンプレートとして使っていました。そのコードを参考にして theme で再実装してみました。

gatsby-crudzoo

theme の作成は下記を参考にしました。

Gatsby Themes: Watch Us Build a Theme Live

theme 作成時にはまったところ

markdown に hot reload が効かない

通常ファイルの hot reload は効くのに、markdown ファイルを更新しても更新が反映されず、もう一度 gatsby develop したら反映される状態になりました。

これは gatsby-node.js で markdown ファイルの情報を取得し、template にデータを渡して表示していたことが原因でした。gatsby-config.js や gatsby-node.js は hot reload の対象外ということです。なので、gatsby-node.js では対象ファイルの id を取得して、template でその id を使って query でデータを取得する手順にすると解決します。

//blog-posts.tsx
export const query = graphql`
  query BlogPostQuery($slug: String) {
    allMdx(filter: { id: { eq: $slug } }) {

gatsby-node.js の方でサイトタイトルや content を取得して pageContext で流す方でも表示はうまくいくのですが上記の問題があるので避けています。

gatsby のバージョン

theme 作成を始めた時は version2.5 くらいだった gatsby、今見たら 2.8.4 が最新でした。gatsby 本体もプラグインも更新頻度が高いので、自身の theme も更新頻度は高めにしていく予定です。

作業中に良くわからないエラーが出た時は、バージョンを細かく切り替えてみると修正されているケースがありました。下げすぎると使用できない API が出てきますので新しい方に寄せるのが良いと思います。

React 自体も変化がありますし、面白い反面、2 年くらいのスパンでみた時の保守はどんな感じなのか気になるところです。

graphql

mdx での graphql はサンプルが少なくて困りました。gatsby develop 中の graphql 画面で、explore で現状の query を確認することができます。frontmatter が最新の状況にならない時は、キャッシュをクリアすると大抵は上手くいきます。

static query と普通の query

比較的新しいバージョンには static query という機能があります。パフォーマンスに違いがあるのかはわからないですが大きな違いとして、static query には変数が使えません。なので、サイトタイトルや作者など動的に変化する情報が必要ないものは static query で取得。header や footer、bio などはこれに該当。

ブログポストなど template に流し込むようなものは通常の query で取得(id を受け取ってその id を変数として扱うので)としました。

ファイル依存の問題

ライブラリではあるものの、theme は使用されるプロジェクトのフォルダー構成や設定ファイルに大きく依存しています。 なので、theme 側がフォルダー名や必要ファイル、query の変更をすると破壊的なアップデートになりやすく、スターターテンプレートと比較してどれだけメリットを受けられるのかはこれからの開発次第なところです。

今のところは wordpress のテーマのように、着せ替え感覚で theme を変更できるようなものではありません。完全にルールを統一した上でなら擬似的には出来そうですが、experimental な状況でやることではないでしょうね。

Todo

少しずつ更新する予定。

  • Component Shadowing しやすいようにファイル構成を考える

  • template の追加(ドキュメントっぽい見た目のページが欲しい)

    gatsby-crudzoo

2021/04/23 追記

コメントにて動作しないと報告がありました。週末か GW に gatsby@3 以降の対応や master ブランチと今の状態(このサイトの状態)が剥離しているので整理します。