Live reloadの実装

このブログを生成するためのプログラムであるnaoty/blogには、プレビュー機能がある。

% blog serve <記事を含むディレクトリ>
[2022-07-27 21:49:33] INFO  WEBrick 1.7.0
[2022-07-27 21:49:33] INFO  ruby 3.1.0 (2021-12-25) [x86_64-darwin20]
[2022-07-27 21:49:33] INFO  WEBrick::HTTPServer#start: pid=2299 port=8080

このアプリケーションは、リクエストを受け取ったら、パスにマッチするmarkdownファイルをパースしてHTMLを生成し、それを静的ファイルとして返す。シンプルなRackアプリケーションとして実装し、webrick上で動かしている。

最近、このプレビュー機能にLive reloadの機能を実装した。記事の元になるmarkdownファイルを編集し保存すると、その変更が自動的にブラウザに反映される。といっても、モダンなWebフロントエンド開発に備わっているような高度なものではなく、setIntervalで定期的にリクエストを送り続けるだけのものだ。

sequence

図にしてみた。[200, env, HTML]とか書いてあるのはRackアプリケーションの#callの返り値のイメージ。

定期的にリクエストを送るスクリプトは、サーバーがHTMLをmarkdownから生成したあとに<script>を挿入してからブラウザに返すことでブラウザから実行される。fetchを使ってリクエストを送り、レスポンスに含まれるHTMLをdocument.writeを使って雑にページごと書き換えるようにした。

それと同時に、サーバー側でHTTPキャッシュの仕様に準拠するようにし、元となるmarkdownファイルに変更がなければ304を返すようにした。具体的には、ブラウザから送られたIf-Modified-Sinceヘッダの値とファイルのmtimeを比較して判定した。


こういった実装のおかげで、ブログの執筆作業がかなりスムーズにできるようになった。

naoty/blogに手を入れるのは1年ぶりくらいのはずだけど、手に馴染んだRubyでフルスクラッチしていたおかげで改修もスムーズだった。まだ足りていない機能がいくつかあるので、naoty/blogを継続的にメンテナンスしていきたい。