如何重新编译 Elixir 项目并从 iex 中重新加载它?

How do I recompile an Elixir project and reload it from within iex?

我目前正在通过 elixir-lang 网站上的 OTP 和混合教程学习 Elixir,但我无法找到如何从 shell 中重新编译和重新加载项目。

在 Erlang 中,我会做 make:all([load]),它会编译并加载发生的任何更改。然而,在 iex 中总是说 :up_to_date,这确实有意义,因为 Elixir 使用 mix 来满足它的编译需要。

我在 iex 中找不到任何等效项。

您可以使用IEx.Helpers.recompile/0函数。

Recompiles the current Mix application.

This helper only works when IEx is started with a Mix project, for example, iex -S mix. Before compiling the code, it will stop the current application, and start it again afterwards. Stopping applications are required so processes in the supervision tree won't crash when code is upgraded multiple times without going through the proper hot-code swapping mechanism.

Changes to mix.exs or configuration files won't be picked up by this helper, only changes to sources. Restarting the shell and Mix is required in such cases.

If you want to reload a single module, consider using r ModuleName instead.

NOTE: This feature is experimental and may be removed in upcoming releases.

来自https://github.com/elixir-lang/elixir/blob/v1.2.4/lib/iex/lib/iex/helpers.ex#L56-L93

我发现@Dogbert 的回答的一个缺点是它会完全停止并重新启动应用程序。虽然这在理论上是可以的,但在我当前的项目中失败了,因为我的项目依赖于 Ranch,但一切都没有正确停止。这意味着当它试图重新启动项目时失败了,因为套接字已在使用中。

长话短说,我查看了帮助程序的代码并将以下功能添加到我的模块中:

  def recompile() do
    Mix.Task.reenable("app.start")
    Mix.Task.reenable("compile")
    Mix.Task.reenable("compile.all")
    compilers = Mix.compilers
    Enum.each compilers, &Mix.Task.reenable("compile.#{&1}")
    Mix.Task.run("compile.all")
  end  

现在我可以输入 MyApp.recompile 并且无需重新启动应用程序即可热重载所有内容。

2017 年 2 月 26 日:

要在 运行 长生不老药系统中热加载组件,并且出现问题的可能性最低,请使用:

case c(filename_ex, :in_memory) do
    [] -> :ignore
    [mod|_] -> r(mod)
end

原回答:

在 elixir 1.3.0 中,重新编译不再重新启动应用程序。所以检查是否有任何源更改和热加载的正确方法是:

iex> recompile()

注意:我想补充一点,由于在重新编译期间删除模块的问题,如果你有像 gen_statem 和 [=26 这样的正在运行的消息,你很可能会在重新编译时崩溃进程=].

注意 2:使用 recompile/0 如果您在源文件中出错,项目将在缺少并卸载该源文件的情况下进行编译。