🧊

Astroをv5にアップデートしたメモ

祝リリース記念。

Astro 5.0 | Astro https://astro.build/blog/astro-5/

というわけで、このブログもアップデートした。

正直マイグレーションガイドに従っただけではあるが、何をやったか簡単に書いておく。

Upgrade to Astro v5 | Docs https://docs.astro.build/en/guides/upgrade-to/v5/

ちなみに、このブログはただの静的サイトなので、目玉アップデートたちとはあんまり関係がない。

Legacy: v2.0 Content Collections API

Content Collectionsといって、ローカルにおいてある.md.jsonを元に、ページ生成できる機能がありまして。

Content collections | Docs https://docs.astro.build/en/guides/content-collections/

で、これを使うには、

  • ./src/contentディレクトリを切って
  • そこにconfig.ts
  • Markdownなどのコンテンツを配置する

という必要があった。

で、今回のアップデートで、Content Collectionsの内部的な概念として、Content Layerというものが追加された。 これは、ローカルにあるファイル以外にも、CMSやらのリモートにあるコンテンツも透過的に扱えるよってやつ。

その影響を受けて、

  • ./src/contentディレクトリである必要はなくなった
    • ./contentとか別の場所でもいい
  • ./src/content.config.tsで定義を書く

というようになった。

正直./src配下にいるときに、grepとかして過去のブログ記事が引っかかるのが不便だったので、個人的に嬉しい。

content.config.tsの内容としては、loaderというどうやってコンテンツを取ってくるか?の指定をするだけ。 既存のユースケースだったローカルのファイルに対しては、glob()file()といったビルトインの実装が用意されてる。

その他は、.jsonをコンテンツとして使ってた場合、slugというキーを使ってたけど、それがidに統一された。(.mdの場合はもとからidだったので、なぜ・・・ってなってたやつ)

https://docs.astro.build/en/guides/upgrade-to/v5/#updating-existing-collections

そのほかでは、getCollection()した後のソート順が保証されなくなったのも影響が大きかった。 まあソートすればよい。

というわけで、アップデート作業としてはこんなもんだった。

あとはおまけです。

Endpointsのバグ

RSSフィードを生成するのに、Endpointsという機能を使ってた。

これは、pages/rss.xml.tsみたいなのを置けば、そこのロジックからrss.xmlが生成できるやつ。

で、これがastro devしてるときに表示されてなくて、astro buildするとちゃんと生成されるのになんで・・・?ってなってた。

どうやらURLの末尾/に絡んだ別のバグだった。

Unable to generate RSS feed with directory format consistently across DEV and PROD environments · Issue #11447 · withastro/astro https://github.com/withastro/astro/issues/11447

data-store.json

Content Layer APIは、どうやっていろんなソースを抽象化してる?ってのを調べてるときに見つけた。

https://github.com/withastro/astro/blob/10fdf3d23be757432f971738f9174f77f3c8e16b/packages/astro/src/content/consts.ts#L37

どうやら、定義したContent Collectionsからデータを取得してきて、1つにまとめた.astro/data-store.jsonという巨大なファイルを作って、それをストアにしてるらしい。

devalueを使ってMapをそのまま文字列化したもので、各コレクション名ごと、アイテムのidをキーにしてた。

xxhash-wasmを使ってコンテンツのdigestを取って、それで差分を管理してる。

https://github.com/withastro/astro/blob/10fdf3d23be757432f971738f9174f77f3c8e16b/packages/astro/src/content/content-layer.ts#L88

ローカルにあるファイルをコンテンツにしてる場合は、まったく同じだけの文字列がディスクを占有するわけなので、tempファイルとしてそれなりにディスク容量を要求するアーキテクチャになる感じかな。

現時点で700記事くらいしかないこんなブログでも、8.5MBのJSONになってた。

なので、実際にCMSからデータを引っ張ったりなんかしてたら、もっとすごいサイズになるはず。 そのうちSQLiteとかになるんだろうか。サイズはそこまで減らんと思うけど。

コードを見る限り、このDataStoreはLoaderごとに定義できるらしいので、もしかしてリモートのKVSなんかにつなげるか?って邪なことを考えたけど、型がasyncを想定してなさそうだったので諦めた・・・。

Astro Content Loader API | Docs https://docs.astro.build/en/reference/content-loader-reference/#store