delimiter

Astro と Strapi で作るブログシステム

このサイトのフロントエンドを Astro にした。


以前は Gatsby で構築していた。 Gatsby のGraphQLシステムのアーキテクチャは気に入っていたが、いくつかの不満があったし、単純に Astro を試してみたかった。


Gatsby で気に入らなかったのは次のような点。


  • ビルドが遅く、dev server が不安定に感じる
    • 開発している最中に、たびたび再起動が必要になる。
  • 冗長な JavaScript のバンドルがある
  • GraphQLシステムとTypeScriptとの親和性が高くない気がする

近年のトレンドとして、できるだけ react.js をフロントエンドに配信しないフレームワークが求められている。ビルド時に react を静的HTMLにコンパイルしたり、バニラJSにコンパイルしたり。そうしたフレームワークに切り替えたいと思ったし、身近でも Astro の利用事例をよく聞くので、これから仕事で使うこともあるかもしれない。


Astro でのコーディング


Gatsbyから移植する


Astro は JSX で書かれた React のコンポーネントを扱うことができる。 しかし、完全に対応しているわけではない。 例えば、react-helmet のようなパッケージは使えないし、CSSも限られたものしか対応していない。 React 側のCSSをこれまで emotion でコーディングしていたが、emotion はやめる必要がある。今後 Astroのプラグインが作られるかもしれないが・・・。 これは、考え方としてはシンプル。クライアントサイドで動作するコードなら、いくらでも好きなフレームワークで制約無くコーディングできるはずである。事前にコンパイルが必要なコードについては、Astro のシステムが処理する必要があるので、 Astro のプラグインで対応したり、自分であらかじめコンパイルする必要があるというわけだ。


それはさておき、 せっかくなので、 React コンポーネントもすべて Astro の作法にあわせた Astro コンポーネントに置き換えることにした。


Styling in Astro


Astro では、CSSコーディングのためのいくつかのオプションがある。


Styling & CSS


まず Tailwind を有効にした。 CSS言語は、AltCSS無しで、PostCSSのみにした。また、PostCSSプラグインをいくつか入れる。


  • autoprefixer
  • cssnano
  • postcss-nested

を使うことにした。


本文を変換する


私は、Strapiのビルトインのマークダウンエディタで記事を書いている。これまでもHTMLへの変換はフロント(SSG)側に委ねていた。新しいアーキテクチャでも、AstroをビルドするときにマークダウンをHTMLに変換することにした。 ここでいくつかの注意点がある。 Gatsbyでは便利なプラグインによって処理されていたところを、自前のコードで処理する必要がありそうだった。また、Gatsbyでは、react のおかげで楽ができていたところを、あまり react に頼れなくなる。具体的には、HTMLのちょっとした加工を html-react-parser パッケージで行っていたのだが、別の方法でやることにした。


ブログ記事本文の処理には、 unified を使う。 unified は、 remark という名前でも知られる、ドキュメント処理システムだ。unified それ自体は、テキスト文章の処理自体を行うシステムで、文書を AST に変換し、プラグイン・チェーンで処理する流れだ。 remark と呼ばれているものは、 unified + remark-parse + remark-stringify が合体したものだ。 また、Astro も標準対応している MDX (markdown を JSXに変換するシステム)は、バックエンドで unified を使っているので unified プラグインを組み込むことができる。


今回は、以下のようなプラグイン・チェーンと、簡単な独自プラグインを組み合わせることにした。 remark でHTMLを吐かせるのではなく、その後に rehype 形式に変換している。rehype は、HTMLのASTである。rehypeプラグインとして独自処理を挟んでいる。


rehypeImageTransform


Strapi にアップロードされている画像を、sharpで変換してローカルに保存する。 Astro が提供している画像システム をうまく使うことで簡単にできた。 Strapi に画像配信させたくないためにやっている。 ほんとうは picture / source タグでコーディングするのがベターだが、単なるリプレイスにしている。


rehypeLF2BR


改行の感じが好みではないので、いい感じにする。


ほかにも、マークダウンでテーブルなどが書ける GFM や、シンタックス・ハイライトの Prism などをプラグインとして挟んだ。 本文変換の全体像は以下。



だいたい動くようになったので、しばらくブラッシュアップを続ける。 実はまだ CI / CD も作っていないことだし。


以上。