1. はじめに
ここに書いているように現在、ブログははてなブログを使っています。実は以前、はてなダイアリー難民 → Scrapbox ときて、職場の Web ページでブログを書いていた時期がありました。
この時は、Middleman という静的なサイト生成のシステムを利用していました。HAML で記述したものを HTML にコンバートするとともにタグや最近の更新などを自動作成するものでした。将来的には消してしまうので、リンクではなくスクリーンショットを掲載しておきます。
今回、同じ静的なサイト生成を行うことができる astro-notion-blog を知りました。Notion から blog を生成できる点はこれまであった easy-notion-blog と同様です。easy-notion-blog は動的な描画が可能なのでメリットは多いのですが、Notion からデータ取得を行うために、描画に少し時間がかかるのが気になっていました。
astro-notion-blog の方は、以前利用していた Middleman と同様に静的なページを事前に構築するものです。構築には少し時間がかかるものの、一度構築してしまえば単なる Web ページになるため描画は爆速になります。
Middleman は記事の執筆が面倒だったため、最終的には今のはてなブログに移行をしてしまいました。記事を Notion で執筆できるようになると、はてなブログよりも圧倒的に快適になるので、これを機に astro-notion-blog に移行することを検討しています。今回、その下準備を始めてみたので、ここで記事として公開することにしました。
2. astro-notion-blog のサブディレクトリ対応
基本的に astro-notion-blog は基本サーバを持たない人でも運用できるように Cloudflare で簡単にデプロイできるようにデフォルト設計されています。しかしながら、私の場合は職場の Web サーバで運用する予定です。ここで問題になるのがサブディレクトリです。現在、私の研究室のサーバの URL は以下のようになっています。
https://www2.metro-cit.ac.jp/~hkob/
astro-notion-blog は Cloudflare での利用を前提としているため、デフォルトで / に展開されるようになっているようでした。調査したところ、astro 自体はサブディレクトリには対応しているようでした。このことを踏まえて astro-notion-blog をサブディレクトリ対応したので、ここに記録しておきます。
2.1 astro.config.mjs の修正
まず、astro 自体のサブディレクトリは defineConfig の部分でできるようでした。astro.config.mjs の最後の部分を以下のように変更しました。この base を設定することで、yarn dev を実行時もサブディレクトリの下に展開される形になるようです。今回は、~hkob/astro/
の下に一時的にテスト展開し、移行が終わったら ~hkob/
の下に展開するようにしたいと思います。
// https://astro.build/config export default defineConfig({ site: "https://www2.metro-cit.ac.jp/~hkob/astro/", base: "~hkob/astro/" })
2.2 .env の修正
また、.env ファイルには SUB_DIR を追加しました。ここで、先頭に /
をつけ忘れると相対アクセスになってしまうので注意が必要です(実はこれでかなり時間を潰しました)。
SUB_DIR=/~hkob/astro
2.3 server-constants.ts の修正
この環境変数は src/server-constants.ts
にて取り込みます。
export const SUB_DIR = import.meta.env.SUB_DIR
2.4 Layout.astro の修正
src/layouts/Layout.astro
ではいくつか / に決め打ちしている部分があるので、これを上記の環境変数で対応するようにします。まず、先ほど取り込んだ変数値を上部で取り込みます。
import { PUBLIC_SITE_TITLE, PUBLIC_SITE_DESCRIPTION, PUBLIC_GA_TRACKING_ID, SUB_DIR } from '../server-constants.ts'
これで ${SUB_DIR}
としてサブディレクトリが利用できます。変更した部分は以下のとおりです。
const { title = '', description = '', path = `${SUB_DIR}/` } = Astro.props (中略) const siteOGImage = new URL(`${SUB_DIR}/default-og-image.png`, Astro.site) const navItems = [ { label: 'Home', path: `${SUB_DIR}/` }, { label: 'Blog', path: `${SUB_DIR}/blog` }, ] (中略) <a href={SUB_DIR}>{PUBLIC_SITE_TITLE}</a>
2.5 blog-helpers.ts の修正
src/lib/blog-helpers.ts
にはページ間のリンクを生成する処理が書かれています。ここも絶対パスになってしまっているので、SUB_DIR を追加します。こちらも変更部分だけ記述します。
import { REQUEST_TIMEOUT_MS, SUB_DIR } from '../server-constants' (中略) export const getPostLink = (slug: string) => { return `${SUB_DIR}/blog/${slug}` } export const getTagLink = (tag: string) => { return `${SUB_DIR}/blog/tag/${encodeURIComponent(tag)}` } export const getPageLink = (page: number, tag: string) => { if (page === 1) { return tag ? getTagLink(tag) : `${SUB_DIR}/blog` } return tag ? `${SUB_DIR}/blog/tag/${encodeURIComponent(tag)}/page/${page.toString()}` : `${SUB_DIR}/blog/page/${page.toString()}` }
3. Middleman ブログの移行
先ほどの Middleman で作成していたページを 1 ページだけ移行してみます。複製したテンプレートのページに登録してみました。プロパティは以下のようにしました。slug の部分は任意文字列を設定できるのですが、一意に決めるのは面倒なので、日付+通番にしようと思っています。rank については、今後どうやってつけるかを検討します。もしかしたら slug と同じ数字にしてしまうかもしれません。
肝心の本文ですが、元の Web page からそのまま Notion に貼り付けました。pre で書いていた部分は自動的に code block として認識されました。ただし、全て Plain Text になってしまっていたので、言語だけ変更しています。また、Middleman 運用時、画像は gyazo への外部リンクだったので、Notion でもそのまま外部リンクのまま画像が貼り付けられていました。
4. yarn dev でのプレビュー
まずはローカルで表示を確認してみます。以下のコマンドでローカルで Astro サーバが起動して描画を確認できます。base が設定されているので、URL がサブディレクトリ対応できていることがわかります。
yarn dev
URL をクリックするとブラウザで動作が確認できます。Blog にカーソルを合わせると ~hkob/astro/blog
に正しくリンクが貼られています。
さらに移行したページも確認してみました。その後、数ページ移行してみたのですが、うまく移行できているようです。
5. yarn build での静的ページ作成
うまく動いているようなので、本来の目的である静的ページの作成をしてみます。コマンドは以下のようになります。
yarn build
結果は以下のようになりました。dist フォルダの下にそれぞれの html ファイルが生成されていました。blog/[slug].astro の作成結果を見ると、Notion API からのブロック取り出しがかなり時間がかかるようで 10秒から20秒程度の時間がかかるようです。ページが多くなると build に時間がかかってしまうようです。
6. yarn build:cache でのキャッシュを使ったページ作成
ここから先は調査不足でまだ正しく動作しているのかが確認できていません。Cloudflare ではビルド時間に 20 分の制約があるそうです。ページ数が増えるとこの制約に引っかかってしまってビルドに失敗してしまう可能性があるとのことです。astro-notion-blog では Nx cloud へのキャッシュをすることで、その制限を回避するようにしているようです。詳しくはこちらの記事で紹介されています。
Nx の設定をしなければとりあえず、ローカルにキャッシュだけ作ってくれないかなと淡い期待を持って、yarn build:cache
を実行してみました。
hkob@hM1Pro ~/D/a/astro-notion-blog (main)> yarn build:cached yarn run v1.22.19 $ npm run cache:fetch && astro build > astro-notion-blog@0.2.0 cache:fetch > node scripts/blog-contents-cache.cjs @notionhq/client warn: request fail { code: 'unauthorized', message: 'API token is invalid.' }
上記の結果を見て分かるように Notion API の呼び出しで unauthorized になってしまっています。どうやら内部で呼ばれている node scripts/blog-contents-cache.cjs
が .env から環境変数を読むように設計されていないようです。そういうことなら、.env の環境変数を事前に設定するようにすればよさそうです。
実際にページ作成の時間がかなり削減されています。また、以下のように block.json などの情報が tmp の下にキャッシュもされています。Nx の設定はしていないので、特に外には迷惑をかけていないと思うのですが、後でちゃんと確認しておく必要はあるかと思っています。
7. Web サーバへのデプロイ
ここまで動いたらあとは Web サーバへの転送まで一気に実施する Makefile を書けばよさそうです。
exec: env `cat .env | xargs` yarn build:cached rsync -avr --delete dist/* www2.metro-cit.ac.jp:public_html/astro
これで make コマンドで build から転送までが一気に行えます。転送したページはこんな感じになりました。
8. 終わりに
とりあえず astro-notion-blog でページが作成できることは確認できました。cache のところが少し怪しいですが、来週座談会で、おとよさんと話ができるので、この辺りの動作を教えてもらおうと思います。
とりあえずこのままでもいいのですが、slug は日付から Formula で作成したいですね。rank も同じようにそれを Formula で数値にすれば自動的に並びそうです。データベースを修正したときに、astro-notion-blog の方をどう修正するかは Next action にしたいと思います。