在文件保存时重新加载 Suave 应用程序

Reload Suave App on File Save

我最近开始使用 Suave;我使用 yeoman 和 F# 生成器设置了一个项目。对于 运行 应用程序,我使用 Fake 构建了一个可执行文件,然后 运行 它。每当我更改任何应用程序文件(即 *.fs 文件)时,我都必须重复构建和 运行ning 可执行文件的过程。

是否有更好的开发流程,其中应用重建或 reloads/restarts 文件保存?

F# Snippets project 的构建脚本正是这样做的。

我们的想法是您有 app.fsx 文件定义了一个名为 app 的顶级 WebPart。您可以查看 F# Snippets here 的示例。 app.fsx 脚本文件还可以加载其他文件,因此您可以按照需要的任何方式构建应用程序。

然后build.fsxbuild script启动一个服务器, 监视源代码和 app.fsx 的文件系统更改,并在后台使用 F# Compiler Service 重新加载它,并将 "currently loaded" 服务器替换为从新的 app 值获得的服务器。

当前构建脚本的唯一限制是它没有正确地释放内存(它可能应该通过在构建脚本中重新创建 F# Interactive Session 来修复),因此在大量重新加载后它会耗尽内存.但是,它仍然使工作流程变得更好!

我使用与 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()
)