2022-02-12

CSRからSSG へ

このブログの作りをClient-side renderingからStatic site generatorに変更したときのメモです。

ref. この時点のソースコード (このあとも実験的に変更する可能性が高い)

Table of Contents

そもそもなぜCSR?

具体的な動き (例: https://iinm.github.io/posts/?post=2022-02-12--hello-ssg)

  1. ブラウザでこのURLにアクセスすると posts/index.html をGETする。
    • HTMLの内容は空で、コンテンツを別途取得して描画するためのJavaScriptが記載されている。
  2. query parameterからMarkdownファイルのURLを組み立ててGETする。
  3. Markdown の構造を解析してHTMLに変換。タイトル、本文を書き換える。

ref. CSRだった時のソースコード

CSR だと何が問題か?

(予想はしていたが) 検索エンジンにインデックスされないことが一番の問題です。 趣味とはいえ、実用性を無視して作っていては実世界で役に立つ学びは得られないので方向性を改めることにしました。

以下は、各サイトでの検索結果です。 (site:iinm.github.io で検索)

Search EngineSearch Result
Google
Bing
DuckDuckGo

※ Googleでの検索結果のみスマホから (古いURLをSearch Consoleから削除してしまったため、以前撮ったスクショを使用)

基本に戻って普通に HTML を返す

Jekyll、Hugoなど便利そうなStatic site generatorがいくつかありますが、 引き続き Webの基礎を学ぶために、これまでに作ったものをベースに簡易的なsite generatorを作りました。

CSR 版からの変更内容

このほか、TypeScriptへの書き換えとテスト環境 (Jest) のセットアップをしました。 型をつける過程で意図せずundefinedを返す関数が見つかったり、LSP の補完が効くようになったり、開発者体験が大幅に改善されました。

現時点ではまだ検索エンジンにインデックスされていないので、しばらくこの状態で様子をみます。

(おまけ) Headless Chrome を SSG として使う

最終的には、開発者体験が良くて既存のコードが流用できるTypeScriptでの実装を選びましたが、 試行錯誤の過程でHeadless Chromeを使えば既存のコードのままでもHTMLを作れることに気が付きました。

sh
# 開発用のサーバ起動
python -m http.server --bind 127.0.0.1 8000

# Headless Chromeで記事を描画、HTMLを出力する
find posts -name '*.md' \
  | xargs -n 1 basename \
  | sed 's,\.md$$,,g' \
  | xargs -I {} bash -c "google-chrome-stable --disable-gpu --disable-software-rasterizer --headless --virtual-time-budget=5000 --dump-dom 'http://127.0.0.1:8000/posts/?post={}' > posts/{}.html"

ref. Makefile