astro logo

ブログをAstroで組み直した

2023年01月19日

Gatsbyで組んでいたブログをAstroで組み直しました。

20230120 01

動機

Gatsbyでこのサイトを組んだのは2020年の末なので、もう2年ほど経つ計算になります。当時Gatsbyはv1系からv2系への移行期でしたが、現在はv5となっています。その間細々とした改良は入りましたが、Next.jsなどの進歩を考えるとあまりにも変わらなさすぎたと思います。

またこのブログのビルドに使っていたGatsby Cloudは、サービスイン当初こそビルドが高速でストレスなく執筆ができたのですが、2022年頃よりCMSプレビューがうまく動作しなくなり、ビルドにも3分ほどかかるようになっていました。CMSプレビューは最悪なくてもよいので、より高速なビルドができるフレームワークがあれば、採用したいと思っていました。

Astroと原点回帰

トップページにも書いている通り、私がHTMLとCSSを書くだけの存在からWeb開発という方向に進むきっかけになったのはJekyllです。JekyllはRuby製の単純なWebサイトジェネレーターで、クライアントサイドにJavaScriptを埋め込むようなことはありません。

astro logo

AstroはTypeScriptで作られており、開発環境も現代的なWebフロントエンドのそれではありますが、生成されるWebページにはデフォルトではJavaScriptが埋め込まれることはありません。ある意味原点への回帰ということで、Astroの存在を知った時点でこのブログに使うことは考えていました。

Contentfulとの統合

前回のAstro記事で懸念点に挙げたContentfulとの統合ですが、これは思っていたほど難しいものではありませんでした。

export const getStaticPaths = async () => {
  const entries = await contentfulClient.getEntries<Post>({
    content_type: "post",
  })
 
  const mdToHTML = async (md: string) => {
    const parsed = await unified()
      .use(remarkParse)
      .use(remarkGfm)
      .use(remarkRehype)
      // @ts-ignore
      .use(rehypePrettyCode, {
        theme: ctpMacchiato,
        keepBackground: true,
      })
      .use(rehypeStringify)
      .process(md)
 
    return String(parsed)
  }
 
  const pages = entries.items.map((item, index) => ({
    params: {
      year: dayjs(item.fields.date).format("YYYY"),
      month: dayjs(item.fields.date).format("MM"),
      slug: item.fields.slug,
    },
    props: {
      title: item.fields.title,
      date: item.fields.date,
      cover: item.fields.cover.fields,
      body: mdToHTML(item.fields.body),
      prev: entries.items[index - 1]?.fields,
      next: entries.items[index + 1]?.fields,
    },
  }))
 
  return pages
}

AstroのダイナミックルーターはNextのものによく似ているので、あちらに慣れているとわかりやすいと思います。ContentfulのSDKも特に扱いに難しい点はありませんでした。

NewtやStoryblokといった新しめのCMSや、Contentfulでもリッチテキストを使うとHTMLが直接CMSから降ってくるのですが、このブログはマルチラインテキストにMarkdownをそのまま流し込んでいるため、CMSからはMarkdownが出てきます。これはAstroは特に何もしてくれないので自前でパースするしかないのですが、Gatsbyも内部で使用しているRemark+Rehypeで行うことにしました。

唯一苦労した点はシンタックスハイライトなのですが、これはRehype用のちょうど良いプラグインを見つけることができました。Visual Studio Code用のJSONテーマをそのまま読み込むことができる(!)という代物なので、気に入ったテーマを引っ張ってきて使っています(MITライセンスなので特に問題はないはずです)。

UnoCSS

これは本来はSTREAM@Sで試したみたかったものなのですが、現時点でUnoCSSがNextに対応していないということでこのブログの構築で試してみることにしました。

20230120 02

Tailwindと比べるとかなり高速で、CSSのビルドを意識する場面が無いのですが、classが大変なことになるのは結局Tailwindと同じですね。@applyディレクティブとAstroのインラインスタイルを上手く使っていこうと思います。

今後

パフォーマンス含めていくつか改善点があるので、暇を見ていじり回そうと思います。特にRSSはGatsbyで組んでいた時は配信していたのですが、今回いったん切ってしまっています。