astro logo

Astroを試してみる

2022年12月13日

これからはJamstackだと常々言っているわりに、最近新しいジェネレーターを試していませんでした。2022年8月に1.0に到達したばかり、新進気鋭のAstroを試してみます。

昨今のJamstackフロントのメタ

Gatsbyがv1に到達したのは2017年ですから、今から5年も前。Webフロントエンドの世界では太古の昔です。その間にも多くのジェネレーターがリリースされていますが、2021年辺りからメタが一周し、特定のJavaScriptフレームワーク等に依存しないものがまた流行りだしたように見えます。Eleventyなどがよい例ですね。

他方でNetlifyの調査では、ここ1年でGatsbyのシェアとユーザー満足度がだいぶ落ちてきているようで、落ち目のフレームワークという扱いになってきているようです。Gatsby 5ではSlices APIによるビルドの高速化、Partial HydrationによるJavaScriptの減量といった昨今のトレンドに合わせた新機能が導入されていますが、Webpackですべてをバンドルするのがすでに古い考え方になってきていること、Reactで何か組みたいならNextで大抵なんとかなること、Slicesを使ってもやっぱりビルドが遅いことなどが不満の要因になっているのではないかと思っています。

Eleventyも使っていました

ところで私はkitahina.coという小規模なファンサイトをやっています。元々はこのブログを置いていたドメインなのですが、特定のキャラクターの名前のドメインハックなURIに個人のブログを置くのはよくない、ということで現在の形になり、一応喜多日菜子に関係するものを置いています。

このサイトは当初はEleventyで構築されていました。Nunjucksなどでテンプレートを作っておいて、Markdownを置くとそれに応じてHTMLを生成してくれる、というたいへんシンプルなジェネレーターで、Nodeで構築されていますが生成物にはJavaScriptは(デフォルトでは)乗りません。テンプレート言語はNunjucksを含めて11種類使えて、使い慣れたものがあればそちらで書くこともできます(おそらくこれがEleventyという名前の由来なのでしょう)。

Gatsby v5に向けた実験として11月頭に解体し、Gatsbyでの組み替えを行いましたが、この超小規模サイトでもVercelでのビルドに短くて30秒ほど、コードをいじった場合だと1分30秒ほどもかかっていました。

Astroを試してみる

Astroの新規プロジェクト作成は、グローバルに何かパッケージを入れなくてもできるようになっています。

npm create astro@latest

元々MDXを使っていたので、MDX対応にしてみます。

npx astro add mdx

Integrationsと呼ばれる機能追加は専用のコマンドが用意されており、こちらでもnpmを自分で触る必要がないのは手軽でよいですね。パッケージの追加が終わったら、/src以下にGatsbyで構築したサイトで使っていたmdxを移してきます。

MDXからはGatsby由来のimport文や、レイアウトコンポーネントで囲っていた部分を消し、フロントマター内で使うレイアウトを指定します。<Link><GastbyImage>などGatsbyに組み込まれているコンポーネントを使っていた場合は、<a><img>などのふつうのHTMLに書き換えておきます(画像の最適化パイプラインはAstroにも用意されています)。

---
layout: ../layouts/Layout.astro
---

レイアウトも作りましょう。Astroのテンプレートエンジンは独自のものですが、ほとんどHTMLなので迷う所はないはずです。Markdownのフロントマターのように上部をハイフン3つで区切り、そこにimport文などを書くのがユニークですが、これがJSXなどと比べてもわかりやすいのです。

いったん動かしてみます。

npm run dev

数秒で開発サーバーが立ち上がり、アクセスできるようになります。mdxを書き換えればホットリロードになります。何かエラーがあった場合はブラウザ側にも出てきますが、時折いきなり開発サーバーが落ちる挙動になることがあるのと、エラーメッセージがややわかりにくい所は課題点かもしれません。

コンポーネントもAstroのテンプレートエンジンで書けますが、何かインタラクティブな要素を入れたい時にはReact, Vue, SvelteなどのJavaScriptフレームワークで書くこともできます。ただこれを使って、Gatsbyで組んでいた頃に使っていたYouTubeの動画を埋め込むReactコンポーネントをそのまま使おうとしたところうまく動作しなかったので、完全な互換性があるわけではないようです。

スタイルシートはコンポーネントやレイアウトの中に<style>タグで生のCSSを書くと、自動的にスコープがそのコンポーネント/レイアウトの中に限定されます。CSS-in-JSと格闘する必要はありません。またCSSを外に書いてインポートしたり、CSS Moduleを使うこともできるようです。またこのところ流行ってきている感のあるTailwindに関しては専用のIntegrationが用意されているので、コマンド一発で導入できます。この辺りのよしなにやってくれる感はEleventyにはなかったものです(あちらも然るべき設定をすることでこういった挙動にできるのかもしれませんが……)。

結果として作業をはじめて2時間ほどで完全移行となりました。プルリクエストとしてはこんな感じで、ざっくり28000行ほど削ったことになるようです(!)。そのほとんどはpackage-lock.jsonであり、Gatsbyがいかに巨大なフレームワークなのかがわかりますね……。

lighthouse

Lighthouseも測ってみました。トップページはSpotifyのプレイヤーを埋め込んだ影響なのかスコアが奮いませんでしたが、SKK辞書のページなどは100に近いパフォーマンススコアが出ています。

このブログを移行するかどうか?

kitahina.coは数枚のmdxで組まれたとてもシンプルなサイトでした。移行体験はかなり良かったのですが、このブログに関してはもうひとつ、Contentfulからコンテンツを引っ張ってきているということもあり、移行するとしても難航しそうです。

Contentfulからのコンテンツの導入は公式にも解説があり、Contentful APIを自分で触ることになるようです。GatsbyのようにGraphiQLで結果を見ながらクエリを書く、といったことはできません。また記事本文はリッチテキストで書かれていることを想定しているようなのですが、このブログは通常のテキストでMarkdownを使って書かれています。

そしてAstroに統合されているMarkdownサポートは、あくまでMarkdownのファイルをパースしてよしなにルーティングもやってくれる、というものにすぎないようで、CMSからMarkdownが降ってくる場合は自力でRemarkを導入してパースさせる必要があるようです。またGatsbyには記事内の画像をContentfulの画像パイプラインに通して最適化するプラグインがあるのですが、Astroにはありません。

コンテンツを特定のCMSにロックインされているのはよくないとは思うのですが、現実的には70件ぐらいの記事、256個ぐらいの画像をすべて移行するのはなかなか大変なので、移行先も含めていろいろ考えなければいけないでしょう。

今からサイトを組むならオススメです

HTMLとCSSとMarkdownだけわかる人でも、わかりやすいAstroテンプレート記法ですぐにはじめられて、JavaScriptフレームワークを使ったコンポーネントの導入、CMSとの統合といった深い所にも触れやすい、懐の広いジェネレーターです。今からコンテンツ中心なサイト、たとえばブログや読みものメディアといったものを組むならコレでしょう。