先日リニューアルした本サイトについて、使用技術や作業工程ごとに振り返ります。
今回はウェブサイトのフレームワークである Astro を取り上げます。
ここ最近は、ウェブサイトを実装するときの構成として、静的サイトジェネレータは Eleventy、テンプレートエンジンは Nunjucks という組み合わせを多く採用してきました。
今回も候補にはあったのですが、せっかくなので新たなフレームワークに触れてみたかったので、静的サイトに特化している Astro を選択しました。
そのほかの候補としては Next.js がありました。
Astro インテグレーション
見出し「Astro インテグレーション」Astro では、拡張機能のことを「インテグレーション(Integrations)」と呼びますが、本サイトで導入しているインテグレーションは以下です。
@astrojs/mdx
: Markdown を拡張できる MDX ファイルのサポート@astrojs/sitemap
: XML サイトマップ(sitemap.xml)の自動生成
React、Vue、Svelte、といった UI フレームワークは使用しておらず、必要最小限の構成にしています。
画像最適化のインテグレーションについては後述しますが、導入を見合わせました。
Astro コンポーネント
見出し「Astro コンポーネント」Next.js などの他のフレームワークでも主流ではありますが、コンポーネントを組み合わせる手法は、直感的で迷うことが少なく、適度に複雑性を分散することができるので、本サイトのような小規模なウェブサイトでも開発しやすかったです。
また、テンプレート部分に直接 HTML を書くことができるのもうれしいポイントです。
以下、Astro コンポーネントの例です。
なお、本サイトでは使用しておりませんが、React などの UI フレームワークを使った場合には、Astro アイランド(コンポーネントアイランド)の恩恵も感じられるかもしれません。
ビルド
見出し「ビルド」Eleventy の場合には、基本的に HTML のビルドに限定するので、CSS や JavaScript のビルドは自前で用意する必要があるのですが、Astro では最初からこれらの環境が整っているので、ビルド環境を構築する手間がはるかに少なくなりました。
また、Astro はビルドエンジンに Vite を採用しているということもあり、ビルド時間や変更が反映される時間も高速です。
ルーティング
見出し「ルーティング」src/pages
以下にファイルを置けば自動的にルーティングしてくれるため、個別にルーティングの設定をする必要はありません。
また [slug].astro
や [...page].astro
のような動的ルーティングにも対応しています。
ページ分割
見出し「ページ分割」本サイトのブログのトップページではページ分割を実装しており、ディレクトリ構造は以下のとおりです。
src/pages/
└── blog/
├── [...page].astro // ブログトップ
└── renewal-2023.mdx // ブログ記事
この [...page].astro
がブログのトップページなのですが、これを最初は [page].astro
としていました。
しかし、この状態でページ分割を有効にすると、/blog/
にはアクセスできず、/blog/1/
/blog/2/
/blog/3/
と分割されてしまいました。
ファイル名を [...page].astro
と、スプレッド構文の形にすることで、/blog/
/blog/2/
/blog/3/
と、望んでいたとおりに分割されるようになりました。
CSS スコープ
見出し「CSS スコープ」Astro では、コンポーネント内の CSS セレクタには固有の class
が振られます。
例えば、以下のような Astro コンポーネントがあるとします。
出力されるファイルでは、astro-37FXCHFA
のような astro-
接頭辞が付いたユニークな class
が割り振られ、CSS のセレクタにも追加されるため、他のコンポーネントで同じ名前の class
を指定していても競合することがありません。
そのため、BEM のような命名規則を用いた、CSS セレクタの管理から解放されます。
一方で、<script> </script>
で生成した JS は、グローバルスコープになるので注意が必要です。
コンポーネントとして読み込まれた JS が、他のコンポーネントに影響を及ぼす可能性があります。
ブログコンテンツの構築
見出し「ブログコンテンツの構築」Markdown、MDX の両方の形式をサポートしており、ページ分割や RSS 配信も可能なため、ブログコンテンツを持つウェブサイトとの相性はとても良いです。
公式サイトのチュートリアルが「Build your first Astro Blog(ブログを作る)」なので、まずはこのチュートリアルをひととおり試してみるとよいかもしれません。
コードのシンタックスハイライトは、デフォルトの Shiki をそのまま使用しています。
また、Markdown の拡張機能として、見出しの直前にアンカーリンク を表示させるために、rehype-autolink-headings を使用しています。
Astro のペインポイント
見出し「Astro のペインポイント」Astro は総じてパフォーマンスが高く、柔軟性に富んだフレームワークという印象で、これからも積極的に使っていきたいと考えていますが、導入してみて不満に感じた点や、苦労した点も少しだけ見受けられました。
画像最適化
見出し「画像最適化」まず、画像最適化の方法が確立しておらず、不安定な点が挙げられます。
Astro では、画像最適化のためのインテグレーションとして @astrojs/image
または Astro ImageTools
が存在しますが、いずれも安定版ではなく相互に互換性がありません。
本サイトは画像の点数が少なく、SVG 形式が多いという理由もありますが、検討した結果、今回はこれらのインテグレーションの導入は見合わせました。
もし、画像最適化の優先度が高い場合には、割り切っていずれかのインテグレーションを使用するか、画像処理に特化した CDN を使うといった方法を検討することになりそうです。
なお、この 2 つのインテグレーションの比較については、エビスコムさんの以下の記事が詳しいです。
開発モードとビルド後の挙動の違い
見出し「開発モードとビルド後の挙動の違い」開発モード( astro dev
)と、ビルド後のプレビュー( astro build
の後に astro preview
)で、挙動が若干異なることがありました。
具体的には、Google Chrome にて CSS Transitions を指定していると、ページロード時に発火してしまう問題が、開発モードでは発生せずにビルド後のコードにおいてのみ発生しました。
そもそも生成されるコードは異なるので、新たな機能を追加したときには、ビルド後のプレビュー確認は必須だと感じました。
行き詰まったときは
見出し「行き詰まったときは」Astro は比較的新しいフレームワークなので、ウェブ上のリソースはそれほど多くありません。
そのため、問題に直面した時にピンポイントで解決策が見つからないときがあります。
そのようなときには、まずは公式ドキュメントに立ち返るのが基本ですが、Astro のドキュメントサイト自体も Astro で作られており、GitHub リポジトリが公開されているので、それらのソースコードからヒントが得られるかもしれません。
また、公式ドキュメントの英語版と日本語版で翻訳のタイムラグがあるので、英語版のドキュメントで新たな情報が見つかる場合があります。
今後試したいこと
見出し「今後試したいこと」サイトリニューアル公開直前のタイミングで Astro v2 がリリースされたので、その機能はほとんど試せていません。
特に Content Collections については、機能を理解したうえで、必要に応じてこのサイトでも適用していきたいです。
また、現時点ではデータはすべてローカルにありますが、Astro と Headless CMS との連携も試していきたいと考えています。