祝リリース記念。
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は、どうやっていろんなソースを抽象化してる?ってのを調べてるときに見つけた。
どうやら、定義したContent Collectionsからデータを取得してきて、1つにまとめた.astro/data-store.jsonという巨大なファイルを作って、それをストアにしてるらしい。
devalueを使ってMapをそのまま文字列化したもので、各コレクション名ごと、アイテムのidをキーにしてた。
xxhash-wasmを使ってコンテンツのdigestを取って、それで差分を管理してる。
ローカルにあるファイルをコンテンツにしてる場合は、まったく同じだけの文字列がディスクを占有するわけなので、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