いまさらなのですが。
Phoenix app の開発時に、コードを更新したときに自動的に再読み込みをおこなうしくみを file_system というパッケージが担っているということを知りました。
ということなので。
file_system を使ってファイルの更新を監視し Phoenix LiveView を使ってリアルタイムにブラウザの表示に反映するというのをやります。 これはその覚書。
作成
アプリケーションを用意します。
Phoenix 1.5 以降であれば LiveView のためのオプション --live
が追加されているので、それを指定します。
1.5 よりも前のバージョンを利用するばあいはドキュメントのインストール手順に従ってインストールしてください。
$ mix phx.new my_app --live
lib/my_app_web/live/page_live.ex
--live
オプションで生成される LiveView のモジュールを次のように書き換えます。
手作業でインストールしたばあいは新たにファイルを作成します。
ここではモジュール FileSystem のプロセスにディレクトリ /tmp
を監視させます。
また通知を受け取るためのハンドラ handle_info/2
を記述します。
受け取った通知は file_events
という名前のリストに追加しています。
defmodule MyAppWeb.PageLive do use MyAppWeb, :live_view @impl true def mount(_params, _session, socket) do if connected?(socket) do {:ok, watcher_pid} = FileSystem.start_link(dirs: ["/tmp"]) FileSystem.subscribe(watcher_pid) end {:ok, assign(socket, :file_events, [])} end def handle_info({:file_event, watcher_pid, {path, events}}, socket) do {:noreply, update(socket, :file_events, &[{path, events} | &1])} end end
lib/my_app_web/live/page_live.html.leex
LiveView のテンプレートを書き換え(あるいは作成)します。
<ul> <%= for {path, events} <- @file_events do %> <li> <span><%= path %></span> <span><%= inspect(events) %></span> </li> <% end %> </ul>
lib/my_app_web/router.ex
LiveView を手作業でインストールしモジュールを新規に追加したばあいは、LiveView を利用するようにルーティングも変更します。
scope "/", MyAppWeb do pipe_through :browser live "/", PageLive, :index end
実行
Phoenix app を起動します。
$ iex -S mix phx.server
FileSystem のプロセスが監視するディレクトリを操作します。
$ echo hi > /tmp/hi.txt $ echo hello > /tmp/hello.txt
操作と同時にブラウザ上の表示が更新されることが確認できます。