查看源代码 Mix.Project (Mix v1.16.2)

定义和操作 Mix 项目。

Mix 项目通过在一个模块中调用 use Mix.Project 来定义,通常放在 mix.exs 中。

defmodule MyApp.MixProject do
  use Mix.Project

  def project do
    [
      app: :my_app,
      version: "1.0.0"
    ]
  end
end

use Mix.Project

当你 use Mix.Project 时,它会通知 Mix 已经定义了一个新的项目,所以所有 Mix 任务都会以你的模块作为起点。

配置

为了配置 Mix,使用 Mix.Project 的模块应该导出一个 project/0 函数,该函数返回一个关键字列表,代表项目的配置。

可以使用 Mix.Project.config/0 读取此配置。请注意,如果未定义项目,config/0 不会失败;这使得许多 Mix 任务可以在没有项目的情况下工作。

如果一个任务需要定义一个项目或需要访问项目中的特殊函数,则该任务可以调用 Mix.Project.get!/0,如果未定义项目,则会引发 Mix.NoProjectError 错误。

没有一个完整的列表列出所有可以由 project/0 返回的选项,因为许多 Mix 任务定义了自己的选项,它们从该配置中读取这些选项。例如,查看 Mix.Tasks.Compile 任务文档中的“配置”部分。

以下是一些不只由一个 Mix 任务使用的选项(因此将在本文档中介绍)。

  • :build_per_environment - 如果为 true,则构建将按环境进行。如果为 false,则构建将放在 _build/shared 中,与 Mix 环境无关。默认值为 true

  • :aliases - 任务别名的列表。有关更多信息,请查看 Mix 模块文档中的“别名”部分。默认值为 []

  • :config_path - 代表主配置文件路径的字符串。有关更多信息,请参阅 config_files/0。默认值为 "config/config.exs"

  • :deps - 此项目的依赖项列表。有关更多信息,请参阅 Mix.Tasks.Deps 任务文档。默认值为 []

  • :deps_path - 存储依赖项的目录。另请参阅 deps_path/1。默认值为 "deps"

  • :lockfile - mix deps.* 任务系列使用的锁定文件的名称。默认值为 "mix.lock"

Mix 任务可能需要在 def project 中有自己的配置。例如,查看 Mix.Tasks.Compile 任务和所有特定的编译任务(例如 Mix.Tasks.Compile.ElixirMix.Tasks.Compile.Erlang)。

请注意,不同的任务可能共享相同的配置选项。例如,:erlc_paths 配置被 mix compile.erlangmix compile.yecc 和其他任务使用。

CLI 配置

Mix 通常从命令行调用。为此,你可以定义一个特定的 cli/0 函数,它在从 CLI 执行时定制默认值。例如

def cli do
  [
    default_task: "phx.server",
    preferred_envs: [docs: :docs]
  ]
end

上面的示例将默认任务(由 iex -S mixmix 使用)设置为 phx.server。它还将“mix docs”任务的默认环境设置为“docs”。

以下 CLI 配置可用。

  • :default_env - 当未给出环境且未设置 MIX_ENV 时使用的默认环境。

  • :default_target - 当未给出目标且未设置 MIX_TARGET 时使用的默认目标。

  • :default_task - 当未给出任务时调用的默认任务。

  • :preferred_envs - 一个 {task, env} 元组的关键字列表,其中 task 是任务名称(作为原子,例如 :"deps.get"),env 是首选环境(例如 :test)。

  • :preferred_targets - 一个 {task, target} 元组的关键字列表,其中 task 是任务名称(作为原子,例如 :test),target 是首选目标(例如 :host)。

Erlang 项目

Mix 可用于管理没有 Elixir 代码的 Erlang 项目。为了确保 Mix 任务对 Erlang 项目正常工作,language: :erlang 必须是 project/0 返回的配置的一部分。此设置还确保 Elixir 未被添加为依赖项到生成的 .app 文件或使用 mix escript.build 生成的 escript 中,等等。

调用此模块

此模块包含许多返回项目信息和元数据的函数。但是,由于 Mix 在发布期间既未包含也未配置,因此建议仅在 Mix 任务内部使用此模块中的函数。如果你需要配置自己的应用程序,请考虑使用应用程序环境。例如,不要这样做

def some_config do
  Mix.Project.config()[:some_config]
end

也不要这样做

@some_config Mix.Project.config()[:some_config]

而是,这样做

def some_config do
  Application.get_env(:my_app, :some_config)
end

或者这样做

@some_config Application.compile_env(:my_app, :some_config)

摘要

函数

返回构建中的应用程序路径。

返回一个包含伞形子应用程序路径的映射。

返回给定项目的构建路径。

为给定应用程序构建项目结构。

清除当前环境的依赖项。

返回给定项目编译到的路径。

返回项目配置。

返回此项目的项目配置文件列表。

返回配置文件的最新修改时间。

返回存储协议整合的路径。

返回所有依赖项的应用程序名称。

返回给定项目存储依赖项的路径。

以映射形式返回所有依赖项的完整路径。

以映射形式返回所有依赖项的 SCM。

以映射形式返回所有依赖项的依赖项。

确保给定项目的项目结构存在。

如果存在,则检索当前项目。

get/0 相同,但在没有当前项目的情况下会引发异常。

在给定项目中运行给定的 fun

返回存储清单的路径。

返回定义父伞形项目的文件的路径(如果有)。

返回定义当前项目的文件的路径。

如果 config 是伞形项目的配置,则返回 true

函数

链接到此函数

app_path(config \\ config())

查看源代码
@spec app_path(keyword()) :: Path.t()

返回构建中的应用程序路径。

返回的路径将被展开。

示例

如果你的项目定义了应用程序 my_app

Mix.Project.app_path()
#=> "/path/to/project/_build/shared/lib/my_app"
链接到此函数

apps_paths(config \\ config())

查看源代码 (自 1.4.0 起)
@spec apps_paths(keyword()) :: %{optional(atom()) => Path.t()} | nil

返回一个包含伞形子应用程序路径的映射。

这些路径基于 :apps_path:apps 配置。

如果给定的项目配置标识了一个伞形项目,则返回值是一个 app => path 的映射,其中 app 是伞形项目的子应用程序,path 是它相对于伞形项目根目录的路径。

如果给定的项目配置未标识伞形项目,则返回 nil

示例

Mix.Project.apps_paths()
#=> %{my_app1: "apps/my_app1", my_app2: "apps/my_app2"}
链接到此函数

build_path(config \\ config())

查看源代码
@spec build_path(keyword()) :: Path.t()

返回给定项目的构建路径。

构建路径基于 :build_path 配置(默认为 "_build")和一个子目录。子目录基于两个因素构建。

  • 如果 :build_per_environment 被设置为 true,则子目录为 Mix.env/0 的值(可以通过 MIX_ENV 设置)。否则它被设置为“shared”。

  • 如果 Mix.target/0 被设置(通常通过 MIX_TARGET 环境变量),它将被用作子目录的前缀。

最后,环境变量 MIX_BUILD_ROOTMIX_BUILD_PATH 可用于更改此函数的结果。 MIX_BUILD_ROOT 仅覆盖根 "_build" 目录,同时保持子目录不变。它可能有助于出于缓存原因更改它,通常是在持续集成 (CI) 期间。 MIX_BUILD_PATH 完全覆盖构建路径,它通常被其他调用 mix CLI 的构建工具使用。

命名差异

理想情况下,配置选项 :build_path 应该称为 :build_root,因为它将完全反映环境变量。但是,它的名称为了向后兼容而保留。

示例

Mix.Project.build_path()
#=> "/path/to/project/_build/shared"

如果 :build_per_environment 被设置为 true,它将为每个环境创建一个新的构建。

Mix.env()
#=> :dev
Mix.Project.build_path()
#=> "/path/to/project/_build/dev"
链接到此函数

build_structure(config \\ config(), opts \\ [])

查看源代码
@spec build_structure(keyword(), keyword()) :: :ok

为给定应用程序构建项目结构。

选项

  • :symlink_ebin - 符号链接 ebin 而不是复制它
链接到此函数

clear_deps_cache()

查看源代码 (自 1.7.0 起)
@spec clear_deps_cache() :: :ok

清除当前环境的依赖项。

当由于全局状态更改需要重新加载依赖项时很有用。

例如,Nerves 使用此函数在更新系统环境后强制所有依赖项重新加载。它大致如下所示

  1. Nerves 获取所有依赖项并查找系统特定依赖项
  2. 找到系统特定依赖项后,它会与环境变量一起加载它
  3. 然后 Nerves 清除缓存,强制再次加载依赖项
  4. 依赖项再次加载,现在使用更新的环境环境
链接到此函数

compile_path(config \\ config())

查看源代码
@spec compile_path(keyword()) :: Path.t()

返回给定项目编译到的路径。

如果没有给出配置,将使用当前项目的配置。

返回的路径将被展开。

示例

如果你的项目定义了应用程序 my_app

Mix.Project.compile_path()
#=> "/path/to/project/_build/dev/lib/my_app/ebin"
@spec config() :: keyword()

返回项目配置。

如果没有定义项目,它仍然会返回一个包含默认值的关键字列表。这允许许多 Mix 任务在没有底层项目的情况下工作。

请注意,此配置在项目被推送到堆栈后会被缓存。多次调用它不会导致它被重新计算。

不要使用 Mix.Project.config/0 来查找运行时配置。仅将其用于配置项目(如编译目录)的方面,而不是应用程序运行时。

@spec config_files() :: [Path.t()]

返回此项目的项目配置文件列表。

此函数通常用于编译任务中,以在这些配置文件发生更改时触发完全重新编译。

它返回锁定清单,以及 config 目录中所有不以句点开头的配置文件(例如,.my_config.exs)。

注意:在 Elixir v1.13.0 之前,mix.exs 文件也被包含为配置文件,但从那时起它已移至名为 project_file/0 的专用函数中。

链接到此函数

config_mtime()

查看源代码 (自 1.7.0 起)
@spec config_mtime() :: posix_mtime when posix_mtime: integer()

返回配置文件的最新修改时间。

此函数通常用于编译任务中,以在这些配置文件发生更改时触发完全重新编译。出于这个原因,mtime 被缓存以避免文件系统查找。

注意:在 Elixir v1.13.0 之前,mix.exs 文件也被包含在 mtimes 中,但现在不再包含。您可以通过调用 project_file/0 来计算其修改日期。

链接到此函数

consolidation_path(config \\ config())

查看源代码
@spec consolidation_path(keyword()) :: Path.t()

返回存储协议整合的路径。

返回的路径将被展开。

示例

如果你的项目定义了应用程序 my_app

Mix.Project.consolidation_path()
#=> "/path/to/project/_build/dev/lib/my_app/consolidated"

在伞形项目中

Mix.Project.consolidation_path()
#=> "/path/to/project/_build/dev/consolidated"
链接到此函数

deps_apps()

查看源代码 (自 1.11.0 起)
@spec deps_apps() :: [atom()]

返回所有依赖项的应用程序名称。

它们返回的顺序保证按顺序排序以进行适当的依赖项解析。例如,如果 A 依赖于 B,则 B 将列在 A 之前。

链接到此函数

deps_path(config \\ config())

查看源代码
@spec deps_path(keyword()) :: Path.t()

返回给定项目存储依赖项的路径。

如果没有给出配置,将使用当前项目的配置。

返回的路径将被展开。

示例

Mix.Project.deps_path()
#=> "/path/to/project/deps"
链接到此函数

deps_paths(opts \\ [])

查看源代码
@spec deps_paths(keyword()) :: %{optional(atom()) => Path.t()}

以映射形式返回所有依赖项的完整路径。

选项

  • :depth - 仅返回到深度级别的依赖项,深度为 1 将仅返回顶级依赖项
  • :parents - 从给定的父级而不是应用程序根目录开始依赖项遍历

示例

Mix.Project.deps_paths()
#=> %{foo: "deps/foo", bar: "custom/path/dep"}
链接到此函数

deps_scms(opts \\ [])

查看源代码 (自 1.10.0 起)
@spec deps_scms(keyword()) :: %{optional(atom()) => Mix.SCM.t()}

以映射形式返回所有依赖项的 SCM。

参见 Mix.SCM 模块文档以了解有关 SCM 的更多信息。

选项

  • :depth - 仅返回到深度级别的依赖项,深度为 1 将仅返回顶级依赖项
  • :parents - 从给定的父级而不是应用程序根目录开始依赖项遍历

示例

Mix.Project.deps_scms()
#=> %{foo: Mix.SCM.Path, bar: Mix.SCM.Git}
链接到此函数

deps_tree(opts \\ [])

查看源代码 (自 1.15.0 起)
@spec deps_tree(keyword()) :: %{optional(atom()) => [atom()]}

以映射形式返回所有依赖项的依赖项。

选项

  • :depth - 仅返回到深度级别的依赖项,深度为 1 将仅返回顶级依赖项
  • :parents - 从给定的父级而不是应用程序根目录开始依赖项遍历

示例

Mix.Project.deps_tree()
#=> %{foo: [:bar, :baz], bar: [], baz: []}
链接到此函数

ensure_structure(config \\ config(), opts \\ [])

查看源代码
@spec ensure_structure(keyword(), keyword()) :: :ok

确保给定项目的项目结构存在。

如果它确实存在,则为无操作。否则,它将被构建。

opts 与可以传递给 build_structure/2 的选项相同。

@spec get() :: module() | nil

如果存在,则检索当前项目。

如果没有当前项目,则返回 nil。这可能发生在当前目录中没有 mix.exs 的情况下。

如果您希望定义项目,即它是当前任务的要求,您应该改为调用 get!/0

@spec get!() :: module()

get/0 相同,但在没有当前项目的情况下会引发异常。

这通常由需要在项目上定义其他函数的任务调用。由于这些任务通常依赖于项目定义,因此此函数会在没有项目可用时引发 Mix.NoProjectError 异常。

链接到此函数

in_project(app, path, post_config \\ [], fun)

查看源代码
@spec in_project(atom(), Path.t(), keyword(), (module() -> result)) :: result
when result: term()

在给定项目中运行给定的 fun

此函数更改当前工作目录并将给定目录中的项目加载到项目堆栈中。

可以传递一个 post_config,它将被合并到项目配置中。

fun 使用给定 Mix.Project 的模块名称调用。此函数的返回值是 fun 的返回值。

示例

Mix.Project.in_project(:my_app, "/path/to/my_app", fn module ->
  "Mix project is: #{inspect(module)}"
end)
#=> "Mix project is: MyApp.MixProject"
链接到此函数

load_paths(config \\ config())

查看源代码
此函数已弃用。请改用 Mix.Project.compile_path/1。
链接到此函数

manifest_path(config \\ config())

查看源代码
@spec manifest_path(keyword()) :: Path.t()

返回存储清单的路径。

默认情况下,它们存储在构建目录内的应用程序路径中。伞形项目将清单路径设置为构建目录的根目录。在将来的版本中可能会更改目录。

返回的路径将被展开。

示例

如果你的项目定义了应用程序 my_app

Mix.Project.manifest_path()
#=> "/path/to/project/_build/shared/lib/my_app/.mix"
链接到此函数

parent_umbrella_project_file()

查看源代码 (自 1.15.0 起)
@spec parent_umbrella_project_file() :: binary() | nil

返回定义父伞形项目的文件的路径(如果有)。

大多数情况下,它将指向 mix.exs 文件。如果没有在项目中或伞形项目中,则返回 nil

链接到此函数

project_file()

查看源代码 (自 1.13.0 起)
@spec project_file() :: binary() | nil

返回定义当前项目的文件的路径。

大多数情况下,它将指向 mix.exs 文件。如果没有在项目中,则返回 nil

链接到此函数

umbrella?(config \\ config())

查看源代码
@spec umbrella?(keyword()) :: boolean()

如果 config 是伞形项目的配置,则返回 true

当不带参数调用时,会告诉当前项目是否为伞形项目。