2023/12/26

Deno/Lumeでブログ作った

GitHub Gist に書いたMarkdownテキストをブログ形式で表示したくなったので作ってみた.

リポジトリは以下.


https://github.com/toms74209200/gist-blog

実際に作ったブログは以下.

読んだもの
https://toms74209200.github.io/gist-blog/

構成としてはgistに書いたMarkdownテキストをAPI叩いてとってきて, ブログ形式でレンダリングしている.

Denoを選んだのは単純にNode.js / Typescript / Reactが辛いから. Lume[1]はDenoの静的サイトジェネレータ(SSG) で, DenoでReactを使ってSSGするにはこれがデファクトっぽい感じ. Node.jsみたいにトランスパイルしてSPAみたいなのは一般的ではなさそう(Deno Deployを推しているのでそれはそう).

DenoのWebアプリケーションフレームワークとして, Fresh[2]もあるが, これはDenoのNext.jsみたいなものでサーバーサイドレンダリングになるためSSGができない. Deno Deployを使いたいならこっちのほうが情報も多くてよさそうだが, 今回はGitHub Pagesを使いたかったので見送った. ただFreshで作るブログのサンプルをパクった参考にした[3].

Lumeの使いかた

Lumeを使うにあたって, そもそもコンセプトの理解が必要だった. 公式を読めという話だが, 一つのドキュメントで簡単に理解できるほど簡単なことはない. いかんせんLumeの記事は少ないが, [4] が参考になった.

Lumeでは配信可能なドキュメントファイルを自動で収集して配信するらしい.

  • It supports multiple file formats, like markdown, yaml, JavaScript, typescript, jsx and nunjucks, and it's easy to extend with more. [5]

ここでLumeには Page data という概念があり, これを設定することで, そのコンテンツ(ページ)のURLやタイトル, 装飾(layout) などを設定することができる[6]. LumeではビルドするとすべてHTMLドキュメントに変換される. このHTMLドキュメントのファイル名などの設定が Page data によって設定されるため, この概念の理解が重要だった.

動的ページ生成

今回はGitHub Gistからコンテンツをとってくるため, ビルド時まで Page data が決定しない. Lumeは複数のページを動的に生成する方法があるため[7], これを使うとブログのコンテンツページを動的に生成することができる. 今回はブログコンテンツにするgistのIDをあらかじめリストとして用意しておき, そのgistをfetchしてコンテンツページを生成するようにした(以下のJSONの contents がIDのリストにあたる)[8].

{
"title": "読んだもの",
"contents": [
"938ecf2e198e2d29cadbf3f2c49dad58",
"ed540e23f9bc232a09496b9a05b40888",
"56e12dffda03f90b0a096e4f556f6a08",
"24ea1baa3492bb06a31054c19ef26ba9",
"cc55cf604db2dcf679e27099b9ffe366",
"ed8c6b88e18af7a803f0589a980ce73c",
"66ffd3baa97df50170ec074b05dcaebd",
"c189ffa8c91c761b96a715edbdccc3f5",
"fb8d9d5663fec4d6afb5435cd6f4edf3",
"67e3ed039201fca5b6120eb7f3e5ffdd",
"b5a0c5998a5e1178ac95467400a708da",
"083496cd982956a950cfaa3301c1e415",
"7faf020ccc6c97eb1670ab70627888dd",
"bb9a7fb6ab8323513e7e9cb9447888e2",
"09bd5851f986c226382889cf273f9b14",
"a8d11539dbfa09a250ae89c8afbadabd"
]
}
view raw config.json hosted with ❤ by GitHub

Lumeの multiple pages 機能ではコンテンツを文字列型でしか指定できない. なのでJSXでコンテンツを生成するには事前にレンダリングする必要がある. Denoでは preact-render-to-string [9] を使ってJSXをHTML文字列に変換できる.

GitHub Pages へのデプロイ

Lumeの公式にGitHub ActionsでGitHub Pagesへデプロイするサンプルコードがあるので, これをそのまま使えばよい[10].


Denoは開発が日進月歩なので解決策が見つからないことも多いし, 「最近入ったこの機能を使わないと作れない」みたいなことも多い. 正直まだ趣味の域を出ないかなという感じ.

参考

0 件のコメント:

コメントを投稿