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
andnunjucks
, 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" | |
] | |
} |
Lumeの multiple pages 機能ではコンテンツを文字列型でしか指定できない. なのでJSXでコンテンツを生成するには事前にレンダリングする必要がある. Denoでは preact-render-to-string
[9] を使ってJSXをHTML文字列に変換できる.
GitHub Pages へのデプロイ
Lumeの公式にGitHub ActionsでGitHub Pagesへデプロイするサンプルコードがあるので, これをそのまま使えばよい[10].
Denoは開発が日進月歩なので解決策が見つからないことも多いし, 「最近入ったこの機能を使わないと作れない」みたいなことも多い. 正直まだ趣味の域を出ないかなという感じ.
参考
- [1] Lume, the static site generator for Deno - Lume https://lume.land/
- [2] Fresh - The next-gen web framework. https://fresh.deno.dev/
- [3] How to Build a Blog with Fresh https://deno.com/blog/build-a-blog-with-fresh
- [4] Lume入門(第1回) - Denoベースの静的サイトジェネレーターLumeで静的サイトを手早く作る | 豆蔵デベロッパーサイト https://developer.mamezou-tech.com/lume/lume-intro/
- [5] About Lume - Lume https://lume.land/docs/overview/about-lume/
- [6] Page data - Lume https://lume.land/docs/creating-pages/page-data/
- [7] Generate pages from other sources - Create multiple pages - Lume https://lume.land/docs/core/multiple-pages/#generate-pages-from-other-sources
- [8] gist-blog/src/pages/[slug].page.tsx at master · toms74209200/gist-blog https://github.com/toms74209200/gist-blog/blob/master/src/pages/%5Bslug%5D.page.tsx
- [9] preact-render-to-string - npm https://www.npmjs.com/package/preact-render-to-string
- [10] Deployment - Lume https://lume.land/docs/advanced/deployment/#github-pages
0 件のコメント:
コメントを投稿