我目前正在通过在elixir-lang网站上浏览OTP和混合教程来学习Elixir,而我却无法找到如何从shell中重新编译和重新加载项目。
在Erlang中,我会make:all([load])
,它会编译并加载发生的任何更改。但是,iex
总是说:up_to_date
,这确实有意义,因为Elixir使用mix来编译需求。
我在iex中找不到任何等价物。
答案 0 :(得分:78)
您可以使用IEx.Helpers.recompile/0
功能。
重新编译当前的Mix应用程序。
此助手仅在使用Mix项目启动IEx时才有效 例如,
iex -S mix
。在编译代码之前,它将停止 当前的应用程序,然后再次启动它。停止 应用程序是必需的,因此监督树中的流程不会 代码升级多次而不经过代码崩溃 适当的热码交换机制。此{@ 1}}或配置文件的更改将无法获取 帮手,只改变来源。重新启动shell和Mix是 在这种情况下需要。
如果您想重新加载单个模块,请考虑使用
mix.exs
代替。注意:此功能属于实验性功能,可能会在即将发布时删除 版本。
来自https://github.com/elixir-lang/elixir/blob/v1.2.4/lib/iex/lib/iex/helpers.ex#L56-L93
答案 1 :(得分:20)
2017年2月26日:
要在运行的灵丹妙药系统中热负载组件,使用错误的可能性最小:
case c(filename_ex, :in_memory) do
[] -> :ignore
[mod|_] -> r(mod)
end
原始答案:
在elixir 1.3.0中,重新编译不再重新启动应用程序。因此,检查是否有任何源更改和热负载的正确方法是:
iex> recompile()
注意:我想补充一点,由于在重新编译期间删除模块的问题,如果你有一个带有state_timeout的gen_statem等飞行消息,你很可能会在重新编译时崩溃进程。
注意2:如果在源文件中出错,则使用recompile / 0,项目将在缺少并卸载该源文件的情况下进行编译。
答案 2 :(得分:6)
我发现@ 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
并且在没有重新启动应用程序的情况下热重新加载所有内容。