Astro logo truck

Tech

【Gatsby→Astro】サイトの引っ越しをした

Gatsbyに見切りをつけてAstroに全記事とページを移行しました。色々と発見があったので、簡潔に今の感想を語ります。

2025/12/21

2週間ぐらいかかり、やっと引っ越しが終わりました。

alt text

なぜGatsbyを見限ったか

結論から言えば、開発体験が悪く、数年経っても改善の見込みがなかったからです。

まず言っておくと、Gatsbyは、ビルドして出てくる完成品はもうそれは頬ずりをしたいぐらい素晴らしいものです。Gatsbyよりページ遷移が高速なReactフレームワークを、私は一つとして知りません。

それを帳消しにしてしまうようなデメリットが、開発側にいくつものしかかってくるのです。

「なんか動かない」が多い

Gatsbyは、これがとにかく多い。「開発環境の再現性がない」というのは、安定して色々なものを作り上げていくうえで致命的です。

現代的な開発では、同じ環境を用意…とは行かなくとも、ある程度同じような環境(NodeJSやらなんやら)を揃えてやれば動くようになっているはずです。Gatsbyの場合、たまにそれでも謎のエラーを吐いて急に動作を停止することがあります。調べるよりキャッシュクリアするほうが早いということも非常に多いです。

OSやパソコンによって「こっちではSyntaxErrorが出るのにそっちだと出ない」というのもかなり頻繁にあります。情緒不安定です。

ビルドの結果が環境で異なることがある

これも、Gatsbyを離れることにした深刻な問題です。2年前、GitHub ActionsでGatsbyサイトのビルドを自動化しようとしたときに、Ubuntu環境でビルドするとなぜかaboutの記述内容がホームに来てしまうという酷いバグに遭遇しました。最終的には、ビルド環境をWindowsにするという方法で無理やり解決せざるを得ませんでした。やったことないですが、もしも手元にUbuntu環境があればこの不具合を再現できるかもしれません。めんどうなのでやりません。誰かやってください。

開発サーバーの起動が遅い

むちゃくちゃ遅いです。どれぐらい遅いかというと、HDD時代のパソコンの起動ぐらい遅いです。

これに関しては、GatsbyのせいではなくReactがそもそも重すぎるという問題もあるかもしれません、でも、それにしたって、1分は長いです。ViteやTurbopackなどが存在するこの時代において、Webpackはあまりに遅すぎます。ちょっともう無理です。

あ、ついでに開発環境のページ遷移も遅いです。ひどいときは15秒かかります。

開発の進展がない、コミュニティに活気がない

Gatsbyのコミュニティは、私の見える範囲では、普通に過疎っています。しかも、上記に上げたような不満点は特に直接私がフィードバックしたわけではないものの、この世の誰でも簡単に検証できて不満を抱くことができるポイントです。それが3年、5年経っても修正されないということは、やる気がないのだろうということで見限りました。

MITライセンスのプロジェクトなのに、この点を克服したForkがまったくないのも不思議です。察するに、SSGコミュニティは元から活気がないのだと思います。活気がないコミュニティの中の活気のないフレームワークを使い続けるのは、リスクでしかありません。

引っ越し先の選定

引っ越し先のフレームワークも色々検討しました。Vueは書けないので、Reactを中心に色々探したところ、

の2択ぐらいかな、という結果になりました。

一応VikeもReactで静的サイト生成はできますが、普通に二度とやりたくないです。ググラビリティが終わっています。

Next.jsを選ばなかった理由

Next.jsは、exportの設定を変えるとGatsbyのようにSSGが行えます。Turbopackによるリロードもでき、非常に高速です。開発体験は最高…と言いたいところですが、思わぬ障害がありました。 i18n(多言語対応:Internationalization) です。

実は、Next.jsはi18nでSSGするのが非常に困難です。一応できるらしいですが。「技術的には可能」というやつです。公式ドキュメントにも書いてあります。

Note that Internationalized Routing does not integrate with output: ‘export’ as it does not leverage the Next.js routing layer. Hybrid Next.js applications that do not use output: ‘export’ are fully supported.

引用元:https://nextjs.org/docs/pages/guides/internationalization#how-does-this-work-with-static-generation

日本語でも色々情報は出てきますが、大抵はよく読むとSSR向けです。

https://qiita.com/koshitake2m2/items/dacfdafb833344bada4d

もしNext.jsでi18n入りSSGをしたい人がいれば、この記事はかなり参考になると思います。

https://github.com/martinkr/next-export-i18n

一応こういうのもあります。いずれにせよ、「デファクトスタンダードっぽいものは存在しない」事がわかっていただけると思います。

…実は、別のプロジェクトでNext.js+i18nが使えないか試行錯誤していました。このとき沼りに沼りまして、結果として諦めたわけです。そのため、Next.jsは最初から選択肢に入れませんでした。

Astroとのお付き合い

Astroとお付き合いを始めて、すぐに気づいたことがありました。Reactコンポーネントを含めるとその部分はSSGできません

これはつまり、私の浮気相手であるstyled-componentとの関係に別れを告げなければならないことを意味しています。なんてこった。

そういうわけで、かなり久しぶりにほぼ生のHTMLに近い書き方でサイト作りを始めました。見ての通り、完成しているのですから意外となんとかなりました。

Astroちゃんの不満点

Astroちゃんとの関係性を深めていくにつれ、他にも不満に思うところが出てくるのは仕方のないことです。ちょっと書いてみます。

再読込するとページの先頭に戻される

最近のページは再読み込みをかけても同じ位置にとどまることが多いですが、Astroは先頭に戻されます。おそらくはファーストビュー(読み込んだときに見える部分)以外を後から描画するようにしているせいだと思います。いつか直ることを期待します。

1ファイル1コンポーネントしか書けない

Reactでは以下のような書き方をすることで、1ファイル内に複数コンポーネントを宣言したり、エクスポートやデフォルトじゃないエクスポートをすることができます。

Test.tsx
// 1. 小さな部品(コンポーネント)を定義
const PostHeader = () => {
return <h2>Reactのコンポーネント分割について</h2>;
};
const PostContent = () => {
return (
<p>
Reactでは、1つのファイルに複数のコンポーネントを記述できます。
これにより、関連する小さなパーツをまとめて管理しやすくなります。
</p>
);
};
const PostFooter = () => {
return <small>投稿日: 2025年12月20日</small>;
};
// 2. 上記の部品を組み合わせて1つの「記事」を作る
const BlogPost = () => {
return (
<article style={{ border: '1px solid #ccc', padding: '16px', margin: '10px' }}>
<PostHeader />
<PostContent />
<PostFooter />
</article>
);
};
// 3. メインとなるコンポーネントをエクスポート
export default BlogPost;
// 4. 必要に応じて別の構成(リスト表示用など)もエクスポート可能
export const BlogFeed = () => {
return (
<div>
<h1>最新のフィード</h1>
<BlogPost />
<BlogPost />
</div>
);
};

この1サンプルに、Reactの楽なところが詰まっています。

Astroで似たようなことをした場合、PostHeader、PostContent、PostFooter、BlogPost、BlogFeedは必ずすべて別々のファイルにしなければなりません。めんどくさい。これがあるため、小さいパーツだと普通のHTMLベタ書きみたいになります。案外あまり困らないのでいいんですが、いつかミスを引き起こしたときにバッチリわからなくなりそうです。

…とはいえ、目立った不満点はそれぐらいです。いいところのほうがずっと多いです。

Astroちゃんのかわいいところ

褒めちぎります。

開発環境が速い

超速いです。Turbopackに全く遅れを取りません。中身はViteらしいです。Vite最高。

ついでにBunも使い始めました。速くて最高です。新規パッケージインストールが5秒で終わる。

ビルドも速い

このブログは元からあった記事を30件ぐらい引っ越してきているのですが、全てのページのビルドがCloudflare Pages環境で20秒以下でした。Gatsbyだと平気で5分とかかかるので、大革命です。

読みやすい・簡単

Reactは、初めて見る人にとっては「export constって何?」「なんでこれHTMLタグなのに大文字なの??」「なんでstyle{{}}で囲むの???」「onClickとか久しぶりに見るなあ????」「これTypeScriptと組み合わせたいなら全部型覚えないといけないのか?????」というように、覚えることが非常に多く学習コストがとても高いです。世の中にはNext.jsからいきなりフロントエンドの世界に入る人もいるらしいですが、HTML・CSS・JSが基盤として身についていないと事実上門前払いみたいな状態です。

他方で、Astroは生のHTMLをコンポーネント分割できることを除けば、ほぼすべての部分をそのままHTML・CSS・JSで書けます。この点だけで、圧倒的に他のフレームワークより初心者に優しいと言えます。小学生でも使えると思います。

Astroコンポーネントは、だいたい以下のようになっています。

---
// frontmatterといい、JS式などがかける
// Astroコンポーネントの引数もここに書ける
const { name, age } = Astro.props;
---
<p id="name">{name}さん、ようこそ!(お前は現在{age}歳)</p>
<p id="hint">ヒント:Astroはいいぞ</p>
<!--
適当に羅列した要素がそのまま描画されます。
Reactコンポーネントと違い、複数あってもOK。
あ、ちなみにここに書いたコメントはビルドした後残るので注意
-->
<style>
/*
「pに対してグローバルにスタイルを当てていいのか!?」とか思ってるでしょ。
いいんだな、これが。
Astroコンポーネントは特に指定しなければ勝手にCSSを
スコープ(このファイル以外のpに影響が出ないように)してくれます。
気の利く自慢の彼女です。
*/
p {
font-size: 65535px;
}
</style>
<script>
// なんか書きたければかけます。
// 久しぶりにdocument.getElementByIdを使うことになりました。
document.getElementById("hint").innerText = "ヒント:Astroちゃんはかわいいぞ";
</script>

超カスタムしやすい

AstroはほぼHTML・CSS・JSで書けます。書けますが、もちろんTypeScriptを埋め込んだり、ルーティングを変更したりもできます。ちなみに、このサイトはブログ記事周りのルーティングをかなり大幅に変更しています。

かゆいところに手が届くユーティリティも充実しています。例えば、Astro.urlを呼べばどこのコンポーネントでも現在ユーザーが見ているであろうページのURLを取得できます。i18n環境であれば、Astro.currentLocaleを呼ぶだけで、どこでも安全に現在の言語を呼び出せます。getCollection()を使うと、特定開発環境ディレクトリの中のファイルを読めます。超楽。

GatsbyやNext.jsを使ったことのある人ならわかると思いますが、Reactで現在のURLを取得するには専用のフックを書くなど結構めんどくさいお作法がいります。これがAstro.urlで解決できる柔軟性と楽さは、使ってみた人にしかわからないと思います。

他方、ゴリゴリカスタムをすることもできます。Gatsbyだと「これなにがどう関わってるかわからんから触らんとこ…」となるものが、Astroでは心置きなくゴリゴリ実装できます。


みんなもAstroしようぜ!

そういうわけで、素敵ブログがAstroの手により爆誕しました。実はテンプレートを使わずフレームワークのみで1からサイトを作るのは初めてだったのですが、いい出来になったと思います。この経験を基にしてさっさと未公開Webアプリを作らなければいけません。うごごご

Astroは、Webフロントエンド初心者・未経験者だけでなくフレームワーク経験者であっても最高の選択肢だと思います。想像の100倍簡単なので、気軽に試してみてください。

https://docs.astro.build/en/getting-started/

↑リンクがカードになっていないと思いますが、そのうち実装します。多分すぐできます。