ブログアップグレードで学んだ教訓
Astro、Tailwind、MDX、Pagefind、その他多数!
最近、私は8年以上前に構築したGatsby v1サイトのアップグレードに着手しました。
このブログ記事では、その過程で学んだ教訓と、探求した楽しいテクノロジーについて共有します。
Table of Contents
プロジェクト要件
アップグレードに着手する前に、一連の要件を設定しました。
私のブログは日々のページビュー数が大きく変動するため、静的に事前生成されたサイトが、余計な複雑さを伴わずに望むパフォーマンスを提供してくれると感じました。
また、このサイトの既存のコンテンツと機能を維持する必要がありました。具体的には以下の通りです:
- コードハイライト
- コメント
- サイト内検索
- 既存のReactコンポーネント: クイズUI、Gist埋め込み
- お問い合わせフォーム
- レスポンシブ画像
- 1秒未満の読み込み時間
- ブラウザ互換性: 2018年以降
- 自動化およびPRベースのデプロイ
適切な技術スタックの選択
長年にわたり、私はJekyll、Hugo、Slate、Gatsbyなど数多くの静的サイトツールや、Ember、Knockout、Angular、Vue、そしてもちろんReactといったフロントエンドフレームワークを扱ってきました。
そのため、選択肢は正確に多すぎるほどあり、最終的にRemix、Next.js、Astroに絞り込みました。
評価プロセスだけでブログシリーズが一本書けるほどですが、ここでは要点だけ述べます。
私がAstroを選んだのは、いかに迅速に“意味のあることを実現できるか”が決め手でした。
API設計は驚くほどシンプルです。柔軟性と優れた設計上の意見のバランスが絶妙です。
Astroに明白なクラウドバイアスやフレームワークアジェンダがないことも、少し安心できる点でした。
Astroだけが使用した技術ではありません。以下がスタックの全容です。
- Astro: モダンな静的サイトジェネレーター。
- ShadcnUI: 再利用可能なコンポーネントのコレクション。
- Tailwind CSS: ユーティリティファーストなCSSフレームワーク。
- MDX: Markdownコンテンツ+インラインコンポーネント。
- Pagefind: 高速、静的、オフライン対応のサイト検索ライブラリ。Algoliaは不要!
- Utterances: GitHub Issuesベースのコメントシステム。
- Netlify: 自動デプロイ、キャプチャ付き問い合わせフォーム。
Astro: 学習曲線と主要機能
Astroはすぐに私のアップグレードの基盤となりました。
特に役立った主要機能をいくつか紹介する:
.astroファイル:一見するとReact JSXコンポーネントに見えるが、実際は全く異なり、異なる目的を果たす。(下の比較表を参照。)- 独自のGolang製ビルドツールとViteを採用:そのまま動作する。ESM/CJS、TypeScript、コードバンドル、スタイル、画像などをシームレスに処理。
- フレームワークバイアスもクラウドバイアスもなし。(ゴホン Next.js、OpenNext)
- 静的レンダリングとハイブリッドレンダリング:Astroはほとんどのクラウドプラットフォームをターゲットにする柔軟性を提供:AWS、GCP、Firebase、Netlify、Vercel、Cloudflare Pages、Azure、Fly.ioなど。
- コンテンツコレクション:
getCollectionAPIを使えば、コンテンツファイルをデータソースとして簡単に扱える。 - ファイルベースルーティング:Astroのファイルベースルーティングシステムと
getStaticPathsを組み合わせれば、ページ生成が驚くほど簡単。 - SEO:Astroは邪魔をせず、必要なときだけ最小限の
ゴミボイラープレート(astro-island)を出力する。
少し驚いた点もある。Astroが注入するマークアップ周りのスタイリングや、display:contentsの影響などだ。
<style>astro-island,astro-slot,astro-static-slot{display:contents}</style>.astro コンポーネントとクライアントコンポーネントの比較
Astroコンポーネントは基本的に、強力なコンポーネント&プロップスパターンを備えたHTMLテンプレートである。ビルド時にデータを取得したり、バックエンドリソースにアクセスしたり、機密情報を隠したりできる。
Astroの.astroコンポーネントを理解する最善の方法は、クライアントサイドコンポーネント(React、Vue、Svelteなど)と比較対照することだ。
| 何をする必要があるか? | .astro コンポーネント | クライアントコンポーネント |
|---|---|---|
| 強力なテンプレート+コンポーネントパターンでHTMLを生成する | ✅ | ❌ |
| ビルド時にデータを取得する | ✅ | ❌ |
| バックエンドリソースに(直接)アクセスする | ✅ | ❌ |
| 機密情報(アクセストークン、APIキーなど)を隠す | ✅ | ❌ |
| クライアントサイドJavaScriptを減らす | ✅ | ❌ |
| クライアントコンポーネント(React、Vue、Svelteなど)を使用する | ✅ | ✅ |
インタラクティビティとイベントリスナー(onClick()、onChange()など)を追加する | ❌ | ✅ |
状態とライフサイクルエフェクト(useState()、useReducer()、useEffect()など)を使用する | ❌ | ✅ |
| ブラウザ専用APIを使用する | ❌ | ✅ |
| 状態、エフェクト、ブラウザ専用APIに依存するカスタムフックを使用する | ❌ | ✅ |
モダンCSS:すごい
フロントエンド開発に戻ってきて、ネイティブCSSの進歩に嬉しい驚きを覚えた。
- CSS変数: しばらく前から利用可能で、202*年以降はブラウザ間でかなり安定している。
- ネスティング: ついに仕様化され、以前のぎこちない構文はなくなった。今ではLessやSCSSに似ている。
- 新しいセレクタ:
:is()、:where()、:has()により、要素をより正確にターゲットできる。 ch、vwなどのモダンな単位やclamp()のような関数により、レイアウトやタイポグラフィをより細かく制御できる。-inlineや-block属性を使って、より自然にスペーシングを設定できる。パディングやマージンを水平軸または垂直軸に設定できる。margin: 0 1rem 0 1remの代わりにmargin-inline: 1remと書ける。- 高度なレイアウト: CSS Gridを再学習。いやあ、中身がすごい。使い方は無限にあるように思えて圧倒されるかもしれない。でも、1つか2つの方法を覚えれば十分だ。Gridでトリックをやるのに役立った素晴らしいリソースを紹介する: Kevin Powellの動画: Learn CSS Grid the easy way、メディアクエリなしでレスポンシブ、1行のCSSで実現する10のモダンレイアウト。
検索: Pagefind
サードパーティのサービスやデータベースホスティングを使わずにサイト内検索を実装するのは、面白い挑戦に思えた。何しろ、まだ1万件もの投稿をインデックスするわけではないしね。
Astroのコミュニティ統合を眺めているときに、もっと早く知りたかった素晴らしいツールに出会った: Pagefind。
Pagefindがローカルサイト検索を解決するほど、問題をうまく解決するツールはほとんどない。
Pagefindの実装のシンプルさは喜びだ。あらゆる静的サイトコンテンツと統合でき、デフォルトのUIを使うか、カスタムで何でも構築するかを選べる。
私が望むすべてをきれいに解決してくれた。統合には数分しかかからず、ほとんどの作業は <div id="search"></div> タグを追加してスタイリングするだけだった!
コメント: Utterances
残念ながら、Disqusと長年蓄積してきたコメントに別れを告げなければならなかった。
サイト上のサードパーティスクリプトをより制御・可視化したかった。
また、シンプルで保守しやすいものである必要があった。
そこで、素晴らしいUtterancesサービスを選んだ。GitHub(Issuesベース)のコメントシステムは、私の読者層によく合っている。しかも、セットアップが簡単で無料だ。
Tailwind: 後悔
ただ一つ、使っていることを後悔しつつある技術がある: Tailwindだ。
時間が経つにつれ、記述と保守のコスト差を感じるようになった。Tailwindは記述が非常に速いが、複雑になりすぎると、読み取りや拡張が面倒になる。
結論
古いGatsby v1サイトをAstroを中心としたモダンスタックにアップグレードするのは楽しい経験だった。10/10でおすすめする。
古いサイトのアップグレードや新しい静的(またはハイブリッド)サイトの構築を検討しているなら、Astroをぜひ検討してほしい。学習曲線が急なこともあるかもしれないが、パフォーマンス、開発者体験、プロジェクトの将来性という点でのメリットは、その努力に十分値する。