代码之家  ›  专栏  ›  技术社区  ›  KallDrexx

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

  •  65
  • KallDrexx  · 技术社区  · 9 年前

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

    在二郎我会做的 make:all([load]) 它将编译并加载发生的任何更改。然而,在 iex 总是说 :up_to_date ,这是有道理的,因为Elixir使用mix来满足其编译需求。

    我在iex中找不到任何等价物。

    3 回复  |  直到 7 年前
        1
  •  115
  •   Sam Houston    5 年前

    您可以使用 IEx.Helpers.recompile/0 作用

    重新编译当前的Mix应用程序。

    此帮助程序仅在IEx与Mix项目一起启动时有效 实例 iex -S mix 。在编译代码之前,它将停止 当前应用程序,然后再次启动。停止 应用程序是必需的,因此监控树中的进程不会 当代码在没有经过 正确的热代码交换机制。

    对的更改 mix.exs 否则配置文件将不会被此拾取 helper,仅更改源。重新启动外壳和混合 在这种情况下需要。

    如果要重新加载单个模块,请考虑使用 r ModuleName 相反

    注:此功能是实验性的,可能会在以后的版本中删除 发布。

    从…起 https://github.com/elixir-lang/elixir/blob/v1.2.4/lib/iex/lib/iex/helpers.ex#L56-L93

        2
  •  22
  •   Vans S    8 年前

    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,项目将在源文件丢失并卸载的情况下进行编译。

        3
  •  7
  •   KallDrexx    9 年前

    我发现@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 并且所有内容都是热重新加载的,而不需要重新启动应用程序。