SAFE Stack のアプリケーションからログ出力する続き。 クライアントでログを出力する方法を調べた。

クライアントでは Log.toConsole という関数を使うとブラウザのコンソールにログを出力できた。 これは Elmish の prelude.fs (link) のなかで定義されている。

Log.toConsole の使い方で分ったことを書く。 ただ関数のシグネチャは次のようになっている。

toConsole(text: string, o: #obj)

引数は文字列と (多分) 任意のオブジェクトのタプルで、ログに出力したい情報をこの引数の型に合わせることになる。 オブジェクトのところは、試し範囲では F# の値を無造作に渡すとログに出してくれた。 また、 Program.withConsoleTrace の効果だと思うのだけど、update 関数が呼ばれたときのモデルとメッセージ (ただし整数)、また、ソースを更新してブラウザにホットリロードされたときのログも自動的に出力された。

それから、ブラウザのコンソールを見ていると SocketCluster という JavaScript のライブラリのエラーも出ていて、自分の求めているログを見辛くなっていた。 これは Program.withDebugger を有効にしているときに出るらしい。(link) これをコメントアウトすると SocketCluster のエラーは出なくなった。

SAFE Stack アプリへの反映

上記を SAFE Stack のアプリケーションに反映した。

src/Client/App.fs の変更

diff --git a/src/Client/App.fs b/src/Client/App.fs
--- a/src/Client/App.fs
+++ b/src/Client/App.fs
@@ -14,6 +14,7 @@ Program.mkProgram Index.init Index.update Index.view
 #endif
 |> Program.withReactSynchronous "elmish-app"
 #if DEBUG
-|> Program.withDebugger
+// // This cause frequent error about socketcluster
+// |> Program.withDebugger
 #endif
 |> Program.run

src/Client/Index.fs の変更

diff --git a/src/Client/Index.fs b/src/Client/Index.fs
--- a/src/Client/Index.fs
+++ b/src/Client/Index.fs
@@ -24,6 +24,18 @@ type Msg =
     | DragEnter of string
     | DragLeave of string
 
+let logMessage (msg: Msg) =
+#if DEBUG
+    // Memo:
+    //   - convert the message into string to show its name instead of
+    //     tag number
+    //   - wrap the message string in an array to make browser truncate
+    //     the console message
+    Log.toConsole ("Message:", [| $"{msg}" |])
+#else   // DEBUG
+    ()
+#endif  // DEBUG
+
 type Model = {
     Todos: Todo list;
     Input: string;
@@ -81,6 +93,7 @@ let dropTarget_label2posOpt (label: string) =
         None
 
 let update (msg: Msg) (model: Model) : Model * Cmd<Msg> =
+    logMessage msg
     match msg with
     | GotTodos todos -> { model with Todos = todos }, Cmd.none
     | SetInput value -> { model with Input = value }, Cmd.none