👨‍🚀

Astro v5へのアップデートを機にAstroのコンテンツ取得方法を理解する

に公開

Astro v5へのアップデートを機にAstroのコンテンツ取得方法を理解する#ヌーラボブログリレー2025夏

この記事は、「ヌーラボブログリレー2025 夏」のTechブログ 12日目の記事です。

Astroのバージョンをv4からv5にアップデートした際の備忘録です。今回はv2から存在していたContent Collections、そしてv5から導入されたContent Layerを理解する機会になりました。最近のAstroの状況を追えていない方の参考に少しでもなればと思います。

v5へのアップデート

アップデートは公式ドキュメントに沿って進めます。

npx @astrojs/upgrade

実行すると、下記のような文言が出てきます。破壊的な変更というとちょっと身構えてしまいますね。進めましょう。

Some packages have breaking changes. Continue?

今回アップデートしたサイトに関してはとくにビルドが通らなくなるようなことはなく、下記のような警告だけがでてきていました。

Astro.glob is deprecated and will be removed in a future major version of Astro.
Use import.meta.glob instead: https://vitejs.dev/guide/features.html#glob-import

Astro.globは非推奨となり、将来のメジャーバージョンで削除されるようです。代わりにimport.meta.globを使ってくださいとのことです。

非推奨となったAstro.glob()の代わりに何を使うか

今回Astro.glob()を使ってMarkdownのファイルを取得している箇所がありました。

const posts = await Astro.glob('@src/content/document/**/*.md')

警告では、代わりにimport.meta.glob()を使ってくださいとのことでしたが、Astro.glob非推奨に関するドキュメントをみると、適切な場合はContent Collectionsの利用を検討してくださいという旨の記述があります。今回はまさしく、Content Collections APIのgetCollection()を使ってMarkdownファイルを取得するのが最適でした。

ちなみに、import.meta.glob()getCollection()Astro.glob()と比べてより多くの機能や柔軟性を提供するため、v5では非推奨になったようです。

getCollection()

AstroにはContent Collectionsという機能があります。Astroが用意したコンテンツ管理用のフォルダがsrc/content/で、コンテンツ管理に特化した機能を利用できます。データを取得するためのgetCollection()はContent Collectionsで用意されており、今回はもともとsrc/content/に入っているローカルのMarkdownファイルを取ってくることが目的でしたので、用途としてはばっちり合っていると思います。

ちなみに、getCollection()自体はv2から存在しており、v5になって出てきたものではないので、v4の時点でもこの書き方はできました。このアップデートのタイミングで気づけたことは良かったと思います。Content Collectionsを使うのは、速度の面だけではなく、型安全なデータストアにもなります。

v5からContent Collectionsを引き継いでいるContent Layerについては後に記載します。

import.meta.glob()

こちらはViteの標準機能で、ファイル群をまとめてインポートするための汎用ツールです。画像やCSS、JSONなどあらゆるファイルのインポートに利用できますが、今回の変更にはgetCollection()が適していたため使用しませんでした。細かい仕様に関しては公式のimport.meta.glob()の説明をご覧いただければと思います。

getCollection()に変えてどれくらい速くなったか

Astro.glob()は呼び出すたびに検索処理が走りますが、一方でgetCollection()は一度読み込んだコンテンツを再利用します。複数箇所で同じデータを参照する場合には大きなパフォーマンス向上が見込めます。

実際に今回修正したリポジトリでは、Astro.glob()でコンテンツ取得している箇所が複数あり、それをgetCollection()に変更しましたが、522ページあるリポジトリのビルド時間を31.652秒から19.618秒に短縮できました。

「MarkdownページのContent Collectionsのビルド速度が最大で5倍、MDXでは最大2倍高速になり、メモリ使用量は25-50%削減される」とAstro 5.0 リリースブログに記載があります。今回の修正でメモリ使用量も30%削減されていたので、概ね記載の通りになっているかなと思いました。

Content Collectionsはv5でもっと便利になった

v2で登場したContent Collectionsは、Markdownなどのローカルコンテンツを整理し、型安全を考慮したビルドを行う技術でした。ただ、リモートのAPIを使ってコンテンツを取得することや、数万ページ規模のサイトに対しては、ビルド速度の低下・メモリ使用量の過剰が問題となっていたようです。

それを解決するContent Collectionsの未来版として、v5ではContent Layer APIが導入されました。Content Layerは、Markdown、CMS、APIなど、あらゆるソースからのコンテンツに対応して、データの保存場所によるパフォーマンスを気にする必要がなくなります。サイトをビルドする際、Astroはこれらすべてのソースからデータをロードし、単一の型安全なデータストアにキャッシュして、各ページで利用できるようにします。

公式ドキュメントから引用したContent Layer Architectureの図。あらゆるソースからのコンテンツを単一のデータストアに保存していることがわかる。
Content Layer Architecture(公式ドキュメントから引用)

今回の修正はv5に関係ありませんでしたが、CMSやAPIなどのコンテンツに対しても、Content Layer APIによって速度やメモリ使用量の短縮につなげることができます。

古いContent Collections APIと新しいContent Layer APIはしばらく共存しますが、Content Collections APIが非推奨になってしまう前にContent Layer APIの書き方に変えたほうがよさそうです。

まとめ

今回のアップデートでAstroのコンテンツ管理の仕組みを見直すいい機会になりました。
v5になることで他にも便利になったところはあり、アップデートによってセキュリティ面での懸念も解消されるので、こういったメンテナンスを欠かさずやっていきたいです。

Discussion