私は最近、Suave を使い始めました。私は、yeoman と F# ジェネレーターを使用してプロジェクトをセットアップしました。アプリを実行するには、Fake を使用して実行可能ファイルをビルドし、それを実行します。アプリ ファイル (*.fs ファイルなど) を変更するたびに、実行可能ファイルのビルドと実行のプロセスを繰り返さなければなりません。
ファイルの保存時にアプリが再構築またはリロード/再起動する、開発のためのより良いプロセスはありますか?
F# スニペット プロジェクトのビルド スクリプトはまさにこれを行います。
アイデアは、という名前app.fsx
のトップレベルを定義するファイルがあるということです。ここで F# スニペットの例を見ることができます。スクリプト ファイルは他のファイルをロードすることもできるため、必要な方法でアプリケーションを構成できます。WebPart
app
app.fsx
次に、build.fsx
ビルド スクリプトはサーバーを起動し、ソース コードのファイル システムの変更を監視し、バックグラウンドでF# コンパイラ サービスapp.fsx
を使用してソース コードを再読み込みし、"現在読み込まれている" サーバーを新しい値から取得したサーバーに置き換えます。app
現在のビルド スクリプトの唯一の制限は、メモリが正しく解放されないことです (ビルド スクリプトで F# インタラクティブ セッションを再作成することでおそらく修正されるはずです)。それでも、ワークフローははるかに優れています。
Tomas と同様のアプローチを使用しますが、ビルド スクリプトの子プロセスでサーバーを実行します。これにより、再起動が少し遅くなりますが、メモリやポートがリークすることはありません。これにより、ビルド スクリプトとアプリ スクリプト (この場合は ./app) に別の作業ディレクトリを簡単に使用できます。
これは、私の FAKE スクリプトの縮小版です。
#r "packages/FAKE/tools/FakeLib.dll"
open Fake
let wait() = System.Console.Read() |> ignore
let runServer () =
fireAndForget (fun startInfo ->
startInfo.WorkingDirectory <- "./app"
startInfo.FileName <- FSIHelper.fsiPath
startInfo.Arguments <- "--define:RELOAD server.fsx")
Target "Watch" (fun _ ->
use watcher = !! "app/*.fsx" |> WatchChanges (fun changes ->
tracefn "%A" changes
killAllCreatedProcesses()
runServer()
)
runServer()
wait()
)