我应该在 extra_applications 中包含混合应用程序吗?

Should I include mix app in extra_applications?

我正在使用 distillery 打包 elixir 应用程序,我想在运行时访问当前环境(是 :dev:test 还是 :prod)。

目标是在运行时检查环境,如下所示:

if Mix.env() == :prod do
  # do this only in production
end

在版本中包含 mix 应用程序有什么缺点?

def application do
    [mod: {EvercamMedia, []}, extra_applications: [:runtime_tools, :os_mon, :recon, :mix]]
end

Mix 在生产中被禁用是有原因的,它是一个构建工具,您可以阅读更多关于它的信息here

如果你只需要当前环境,那么你可以这样做:

defmacro env() do
    quote do
      unquote(Mix.env())
    end
  end

但是您需要记住,此代码是在 编译时 评估的,不适用于 runtime 配置之类的东西。

使用mix检测生产环境显然是一种反模式。相反,应该以

开始发布
MY_APP_PROD=true release start

并使用系统环境检查如下图

if System.get_env("MY_APP_PROD") == "true" do
  ...
end

您应该在您的发布中包含mix。您有多种选择:

  • 使用在运行时设置的环境变量,然后:
    • 在代码中使用例如System.fetch_env!.
    • config/runtime.exs中检查它(不是 config/prod.exs;这也在编译时评估)。
  • 或者将 MIX_ENV 的值编译到您的代码中。 @Daniel 提供了一种方法来做到这一点。我提供另一个:
defmodule M do
  @build_env Mix.env()

  def env(), do: @build_env
end

这里的技巧是 @build_env... 语句在编译时评估(当 Mix 可用时),设置属性。然后你可以从你的函数中return它。