Hagakun blog
hero image[object Object]

MDXでブログを構築したくて色々検討した結果、Astroが最強だと気付いた話。


MDX でブログを構築したい

いろんな情報にアクセスして学びが増えていく毎日。
しっかりと記録を残しておくと、必要になった時に利用できるのでとても便利だと思う体験が何度もあったので、技術ブログとして記録を残していくことにしました。

そんな状況で、個人ブログとして要件を決めていくうちに Astro がめちゃくちゃカンタンで使い勝手が良かったのでまずはそれを記事にしていきます。

更新するのは自分だけのブログを構築したい

そもそも書いたことは個人的な内容で、アクセス数やコメントなどを厳密に管理するつもりはありません。したがって、サーバー管理は金銭/人的コスト的に絶対にかからないようにしたいと考えました。

さらに、テーマを使ってしまうとレイアウトの勉強にならないので、これは自分で管理したい。そう考えて CSS の自由度は特に高い構成にしたい。

一番大事なのは、MDX で記事を書きたい!
いちいち html を書くのも面倒ですが、部分的に JSX コンポーネントを利用したいことがあるので、その辺を便利に使い分けできると非常に便利です。

この記事は、これらの要件を充たすために 「Astro が超絶便利だった」というだけの記事です。

Astro, Next.js, Docusaurus の比較

MDX でブログを構築しようとググってみると、だいたいこの辺の技術セットがピックアップされてくると思います。(Astro はまだ若い技術なので選択肢に上がってこない)
わたしなりに比較してみました。

AstroNext.jsDocusaurus
MDX 対応
JSX 対応
ファイルベースのルーティング
Frontmatter
シンタックスハイライト
テーマの多さ
ビルド速度
ドキュメントの充実
ネット情報の多さ

特筆すべき Astro の大きなメリットは、Frontmatter の強力なサポートが得られることです。

js
// example.astro
//Frontmatterに以下のように設定したpublishDateを
---
publishDate: "Aug 15,2022";
---
//.astroファイルの中で以下のように呼び出すだけで使用できます。
const publishDate = post.frontmatter.publishDate;

MDX で作ったブログでも、記事一覧ページを作ったりすることが想定されます。この場合、タイトルやタグなど、mdx で書いた記事の詳細を Frontmatter に書いておいて、「記事一覧ページから呼び出す」といったことをやりたくなると思います。

一方、Frontmatter 部分は公開するブログ記事上には表示したくないですよね。

これが意外と面倒なんです。プラグインや自分で手書きのコードを作って管理する必要があったりして、ほかのフレームワークを用いて MDX ブログを作成する点では非常に面倒なところです。

しかし、Astro ではネイティブでこのような機能が使えるため、面倒な実装を回避しつつ Frontmatter を使った MDX ブログを構築できます。

また、内部では Vite が使われておりビルド速度が非常に高く、MDX を編集しながらホットリロードでプレビューするときのストレスが極小です。 デフォルトでシンタックスハイライトに対応しており、Prism に切り替えることもカンタンです。

完全に体感(測定しろよ)なのですが、Next.js や Docusaurus の場合は、mdx を保存 → ビルド(1 秒)→ 表示という感じ。Astro は mdx を保存 → 表示という感じで、ほとんどビルドが走っている感覚がありませんでした。

Our goal: It should be nearly impossible to build a slow website with Astro.
目標: Astro では遅いウェブサイトを構築することがほぼできないということです。

とあるように、とにかく速度が速い。SEO も強化されており、柔軟に変更可能です。

ネット上の情報は、ほかのフレームワークよりもずっと少ないもののドキュメントはかなり充実しており、導入からデプロイまで特に詰まることなくできると思います。

今回はブログ構築についての記事なので詳しく言及はしませんが、ドキュメントの作成についてはDocusaurusが最もカンタンだと感じました。レイアウト固定で、フォルダ構造に応じたサイドバーを自動生成してくれるため非常に使いやすかったです。

ディレクトリ構造について

├── src/
│ ├── components/
│ │ ├── Header.astro
│ │ └-─ Button.jsx
│ ├── layouts/
│ │ └-─ PostLayout.astro
│ └── pages/
│ │ ├── posts/
│ │ │ ├── post1.mdx
│ │ │ ├── post2.mdx
│ │ │ └── post3.mdx
│ │ └── index.astro
│ └── styles/
│ └-─ global.css
├── public/
│ ├── robots.txt
│ ├── favicon.svg
│ └-─ social-image.png
├── astro.config.mjs
└── package.json

rootページはpages/index.astroです。フォルダ構造がそのままルーティングとなります。このへんはNext.jsやDocusaurusと同じですね。もちろん.astro, .jsx, .tsxなど様々なファイル形式を利用することが可能です。

.astro ファイルについて

Astro に対して一番抵抗感を覚えるのは .astro ファイルじゃないでしょうか。
学習コストが高くなりそうでイヤな感じと思うかもしれません。
しかし、.astro ファイルとは、ただの HTML/JSX スーパーセットであり、特に覚えることもないのでご安心ください。

以下のように、カンタンにコンポーネントとPropsを設定し、利用することができます。

js
// Name.astro
---
const name = Astro.props;
---
<div>
<h1>Hello {name}!</h1>
</div>;
js
// World.astro
---
import Name from './Name.astro';
---
<div>
<Name name={world} />
</div>

このような簡易構文は、jsx や tsx のボイラープレート構文を減らすのに役立つと感じました。とても直感的です。

ドキュメントのComponentsのページに詳しい内容があります。子要素を管理できるSlotなどかなり便利に使えるのでぜひ一読ください。

デプロイについて

to deploy list
このようにたくさんのデプロイ先がドキュメントに記載されています。

無料でStaticなブログをデプロイできればいいので、今回はCloudflare Pagesを使用しました。
SSRを使用しない静的ブログのデプロイ方法については、Cloudflareのページのほうが分かりやすいかもしれません。SSRを使用する場合はWranglerの導入も含めてAstroのドキュメントの方が充実しています。