2025年4月19日
このブログを支える技術2025
このブログは全ページをポチポチHTML書いている訳ではなく、Astroというwebフレームワークによる静的サイト生成(SSG)で作られている。
Astroについて
Astroはコンテンツ駆動型のwebフレームワークで、マーケティングサイトやブログ、コマースなどのWebサイトの作成に特化している。
これだとなんのこっちゃとなるが、例えばこのブログはMarkdownテキストをベースに良い感じに体裁を整えたサイトを出力してくれている。
とにかくパフォーマンスが良いことと、SSGに特化しているということ、何より公式ドキュメントが充実しているのが嬉しい。
ブログ作りたいなーと考え始めた当初はミニマムな技術にこだわり、ビルドツールのviteを使ってのSSGを考えていたもののRouting周りが上手く行かないことが多く、巨人の肩の上に乗る選択を取った。
専門ならもうちょっと模索するべきだったかも知れないが門外漢だからね……。
ブログ本文について
上記でも触れている通り、AstroはMarkdownテキストに対応しており、HTMLに変換してページの生成を行ってくれる。
Markdownのファイルは記事の数だけ増えるが、そのファイル増減に合わせてRoutingを考慮し、Markdown記事の数だけHTMLをビルド生成してくれる。
ブログチュートリアルでは src/pages/
ディレクトリ内に直接.mdファイルを配置し Astro.glob()
で網羅する例となっているが、今回は別のコンテンツコレクションという仕組みを利用した。
こちらは静的出力の対象を拡張したり、markdownに含まれるメタ情報のスキーマ定義を行ったりできる。
今回はMarkdownで生成するHTMLに共通のTypographyスタイルを適用するため、その表示を確認するためにプレビュー用の記事を用意したのだが、これは開発環境でのみ公開される形にしたいという意図があった。
これを以下のようにmarkdownのメタ情報(frontmatter)に isDebugArticle
という形でフラグを持たせることで実現している。
---
title: 'Markdown Preview Article'
pubDate: 1970-01-01
isDebugArticle: true
---
# Markdown syntax guide
## Headers
略
スキーマ定義は公式Docsの例とほぼ同じで src/content/config.ts
で行う。
// 1. ユーティリティを`astro:content`からインポート
import { z, defineCollection } from 'astro:content';
// 2. 各コレクションに`type`と`schema`を定義
const articleCollection = defineCollection({
type: 'content', // v2.5.0以降
schema: z.object({
title: z.string(),
pubDate: z.date(),
isDebugArticle: z.boolean().optional().default(false), // デフォルト値を false に設定
}),
});
// 3. コレクションを登録するために、単一の`collections`オブジェクトをエクスポート
export const collections = {
'article': articleCollection,
};
これでarticleのコレクションにアクセス時にdataからisDebugArticleにアクセスする事が可能になる。
import { getCollection } from 'astro:content';
const isDev = import.meta.env.DEV;
const allArticles = await getCollection('article');
// 開発環境のみ全てのページを返す。本番環境はisDebugArticleがfalseの内容のみ
export function validArticles() {
return allArticles.filter((article) => {
if (isDev) return true;
const { isDebugArticle } = article.data;
return !isDebugArticle;
});
}
スタイルについて
最初はMVP.cssを利用しようとした。
……が作っていくウチに自分の色を出したくなり結局Tailwindcssを採用。
カラースキームを考えたりしたが、結局デフォルトカラーから選んで利用しているので、そのうちカスタムカラーを入れて調整するかもしれない。
レイアウト周りはまだまだ理解不充分なところもあり多少は御愛嬌。
ビルド周りについて
パフォーマンス目当てでpnpmを採用した。が、トップページの画像を扱う際にSharpが無いというエラーが出たり、導入時に色々あったりした。
とはいえ、Astroは公式の選択肢でpnpmをDocsに記載していたのでこれで良かった気がする。
DeployについてはGitHub Actionsで全て処理し、生成サイトはGitHub Pagesにホスティングしている。
Cloudflare Pagesなども気になるがあまりお金を払いたくない気持ちが強い。
GitHub Actionsのworkflowについては全てRoo Code + Claude 3.7 Sonnetにお任せした。
何故かは分からないがGitHub ActionsのYamlなどのCI/CD設定系の作業にAI Agentは強い印象がある。
最初はブログも全部作ってもらうかと思ったが自分が指示する視点として充分なタスク指示を出来なかったので諦めた。
今後について
せっかく作ったので、Sandbox的に好きに動かしてSSGや関連するTypeScriptの知見を深められればと思う。