r7kamura さんのこのサイトの実装 2020年版に倣って、このブログの実装を書いてみる。
ソースコードは全て GitHub に上げてある。
ホスティングとCI
Cloudflare Workers を使って配信している。
CI は専用CLIツールの Wrangler の使い勝手がよく簡単。
GitHub Action も公式から提供されているのがあるのでそれを使うだけ。
TypeScript, React を使っているので Wrangler 組み込みの Webpack でビルドしている。
Webpack がどう動いているのかいまいち掴みきれてないので、 Wrangler のコードを読まないといけない。
投稿の管理
Markdown ファイルを自前で HTML に変換することはせず、GitHub Issues に書くことにした。
画像もサッと入れられるし、モバイルアプリ(GitHub Mobile)から書いたり修正も可能、カテゴリ(タグ)も付けられるし優秀。
ローカルで書くのもお手軽でいいのだけど何か直したくなったときに commit&push が発生するのだるいのと、GitHub Issue のエディタ普段使ってるせいか実は一番しっくり来る感じだったので、Issues をデータストアと見なしたフロントエンドを作ればいいじゃんという結論になった。
データストアとフロント(描画)を API で分離できるので、また違う仕組みに乗せ換えたくなった時にも困らなさそう。
GitHub API v4 は GraphQLで取れるようになっていて、以前と比べて検索クエリも検索結果もカスタマイズ性高くてよい。
Worker のデプロイと記事(Issue)の反映は分けたいなと思ったので、Issueに「public」ラベルを付けるとキャッシュの再生成ジョブがキックされるようにしている。
Workerの実装
GitHub API から取ってきたデータを React で描画するだけのシンプルなアプリケーション。
Cloudflare Workers には Workers Site というHTMLやCSSを静的配信する仕組みがある。Gatsby や Next.js で SSG した結果を使いたい場合はこれを使う。
が、かなりプラットフォーム依存が強まってしまうので、今回は Worker 上で全てのコンテンツを react-dom/server
を使って renderToString
で SSRぽくHTML を返す、Worker として動くようにした。
CSS を link タグで読み込めないのでどうしようかと思ったけど、サイズが大きいわけでもないしインラインで返せばいいじゃんという気持ちになって HTML に含めた。
また、KV というキャッシュとして使えるシンプルな Key-Value ストアが使える。GitHub APIで取ってきた結果も含めたレスポンスをキャッシュするように使っている。
Cloudflare Workerから別のプラットフォームに変えたくなったときに変更が少なくて済むように、index.ts(エントリポイント)と proxy.ts(キャッシュ周り)以外は汎用的になるようにしている。
例えば Firebase Hosting に移りたくなったら renderToString した結果をHTMLファイルに書き出すように index.ts を変更するだけでよいはず。
エッジWorker を使ってみて
エッジかつキャッシュ効かせられるのでとにかくレスポンスが早い。
CSS 込みで 30ms は早い。
Best Practice が93点だけど、なぜか画像ファイルを大きくしろとオススメされていて(バグ?)無視した結果。
パフォーマンスについては全体的に満足。
ネガティブに感じたのは、とにかく Cloudflare Workers の開発事例が少ないのか検索してもヒット件数が少なく参考になる記事も少ない。
ドキュメントを見ても分からないものは手探り感強いこと。これは Worker に限らず Cloudflare 全体に言える話かもしれないですが、もうちょっと開発者のポストが増えるといいなあ。