查看源代码 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.Elixir
或 Mix.Tasks.Compile.Erlang
)。
请注意,不同的任务可能共享相同的配置选项。例如,:erlc_paths
配置被 mix compile.erlang
、mix compile.yecc
和其他任务使用。
CLI 配置
Mix 通常从命令行调用。为此,你可以定义一个特定的 cli/0
函数,它在从 CLI 执行时定制默认值。例如
def cli do
[
default_task: "phx.server",
preferred_envs: [docs: :docs]
]
end
上面的示例将默认任务(由 iex -S mix
和 mix
使用)设置为 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。
以映射形式返回所有依赖项的依赖项。
确保给定项目的项目结构存在。
如果存在,则检索当前项目。
在给定项目中运行给定的 fun
。
返回存储清单的路径。
返回定义父伞形项目的文件的路径(如果有)。
返回定义当前项目的文件的路径。
如果 config
是伞形项目的配置,则返回 true
。
函数
返回构建中的应用程序路径。
返回的路径将被展开。
示例
如果你的项目定义了应用程序 my_app
Mix.Project.app_path()
#=> "/path/to/project/_build/shared/lib/my_app"
返回一个包含伞形子应用程序路径的映射。
这些路径基于 :apps_path
和 :apps
配置。
如果给定的项目配置标识了一个伞形项目,则返回值是一个 app => path
的映射,其中 app
是伞形项目的子应用程序,path
是它相对于伞形项目根目录的路径。
如果给定的项目配置未标识伞形项目,则返回 nil
。
示例
Mix.Project.apps_paths()
#=> %{my_app1: "apps/my_app1", my_app2: "apps/my_app2"}
返回给定项目的构建路径。
构建路径基于 :build_path
配置(默认为 "_build"
)和一个子目录。子目录基于两个因素构建。
如果
:build_per_environment
被设置为 true,则子目录为Mix.env/0
的值(可以通过MIX_ENV
设置)。否则它被设置为“shared”。如果
Mix.target/0
被设置(通常通过MIX_TARGET
环境变量),它将被用作子目录的前缀。
最后,环境变量 MIX_BUILD_ROOT
和 MIX_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"
为给定应用程序构建项目结构。
选项
:symlink_ebin
- 符号链接 ebin 而不是复制它
@spec clear_deps_cache() :: :ok
清除当前环境的依赖项。
当由于全局状态更改需要重新加载依赖项时很有用。
例如,Nerves 使用此函数在更新系统环境后强制所有依赖项重新加载。它大致如下所示
- Nerves 获取所有依赖项并查找系统特定依赖项
- 找到系统特定依赖项后,它会与环境变量一起加载它
- 然后 Nerves 清除缓存,强制再次加载依赖项
- 依赖项再次加载,现在使用更新的环境环境
返回给定项目编译到的路径。
如果没有给出配置,将使用当前项目的配置。
返回的路径将被展开。
示例
如果你的项目定义了应用程序 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
的专用函数中。
@spec config_mtime() :: posix_mtime when posix_mtime: integer()
返回配置文件的最新修改时间。
此函数通常用于编译任务中,以在这些配置文件发生更改时触发完全重新编译。出于这个原因,mtime 被缓存以避免文件系统查找。
注意:在 Elixir v1.13.0 之前,mix.exs
文件也被包含在 mtimes 中,但现在不再包含。您可以通过调用 project_file/0
来计算其修改日期。
返回存储协议整合的路径。
返回的路径将被展开。
示例
如果你的项目定义了应用程序 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"
@spec deps_apps() :: [atom()]
返回所有依赖项的应用程序名称。
它们返回的顺序保证按顺序排序以进行适当的依赖项解析。例如,如果 A 依赖于 B,则 B 将列在 A 之前。
返回给定项目存储依赖项的路径。
如果没有给出配置,将使用当前项目的配置。
返回的路径将被展开。
示例
Mix.Project.deps_path()
#=> "/path/to/project/deps"
以映射形式返回所有依赖项的完整路径。
选项
:depth
- 仅返回到深度级别的依赖项,深度为1
将仅返回顶级依赖项:parents
- 从给定的父级而不是应用程序根目录开始依赖项遍历
示例
Mix.Project.deps_paths()
#=> %{foo: "deps/foo", bar: "custom/path/dep"}
以映射形式返回所有依赖项的 SCM。
参见 Mix.SCM
模块文档以了解有关 SCM 的更多信息。
选项
:depth
- 仅返回到深度级别的依赖项,深度为1
将仅返回顶级依赖项:parents
- 从给定的父级而不是应用程序根目录开始依赖项遍历
示例
Mix.Project.deps_scms()
#=> %{foo: Mix.SCM.Path, bar: Mix.SCM.Git}
以映射形式返回所有依赖项的依赖项。
选项
:depth
- 仅返回到深度级别的依赖项,深度为1
将仅返回顶级依赖项:parents
- 从给定的父级而不是应用程序根目录开始依赖项遍历
示例
Mix.Project.deps_tree()
#=> %{foo: [:bar, :baz], bar: [], baz: []}
确保给定项目的项目结构存在。
如果它确实存在,则为无操作。否则,它将被构建。
opts
与可以传递给 build_structure/2
的选项相同。
@spec get() :: module() | nil
如果存在,则检索当前项目。
如果没有当前项目,则返回 nil
。这可能发生在当前目录中没有 mix.exs
的情况下。
如果您希望定义项目,即它是当前任务的要求,您应该改为调用 get!/0
。
@spec get!() :: module()
与 get/0
相同,但在没有当前项目的情况下会引发异常。
这通常由需要在项目上定义其他函数的任务调用。由于这些任务通常依赖于项目定义,因此此函数会在没有项目可用时引发 Mix.NoProjectError
异常。
在给定项目中运行给定的 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"
返回存储清单的路径。
默认情况下,它们存储在构建目录内的应用程序路径中。伞形项目将清单路径设置为构建目录的根目录。在将来的版本中可能会更改目录。
返回的路径将被展开。
示例
如果你的项目定义了应用程序 my_app
Mix.Project.manifest_path()
#=> "/path/to/project/_build/shared/lib/my_app/.mix"
@spec parent_umbrella_project_file() :: binary() | nil
返回定义父伞形项目的文件的路径(如果有)。
大多数情况下,它将指向 mix.exs
文件。如果没有在项目中或伞形项目中,则返回 nil
。
@spec project_file() :: binary() | nil
返回定义当前项目的文件的路径。
大多数情况下,它将指向 mix.exs
文件。如果没有在项目中,则返回 nil
。
如果 config
是伞形项目的配置,则返回 true
。
当不带参数调用时,会告诉当前项目是否为伞形项目。