Do you want to pick up from where you left of?
Take me there

Umbrella Projects

实际上有时工程项目会变得很大. Mix 构建工具可以让我们将代码划分成多个程序, 使得项目变大的时候更易于管理.

Table of Contents

介绍

创建一个 umbrella project 就像我们创建 Mix project 时一样, 只是多传入了 --umbrella 标志. 下面的例子中我们将创建一个机器学习的命令行工具. 你问为什么是一个机器学习工具? 为什么不呢? 它们将由一些学习算法和通用函数组成.

$ mix new machine_learning_toolkit --umbrella

* creating .gitignore
* creating README.md
* creating mix.exs
* creating apps
* creating config
* creating config/config.exs

Your umbrella project was created successfully.
Inside your project, you will find an apps/ directory
where you can create and host many apps:

    cd machine_learning_toolkit
    cd apps
    mix new my_app

Commands like "mix compile" and "mix test" when executed
in the umbrella project root will automatically run
for each application in the apps/ directory.

正如你在 shell 命令中看到的, Mix 为我们创建了一个项目的框架, 并有两个目录:

子项目

让我们切换到项目的 machine_learning_toolkit/apps 目录并用 Mix 创建三个普通的项目:

$ mix new utilities

* creating README.md
* creating .gitignore
* creating mix.exs
* creating lib
* creating lib/utilities.ex
* creating test
* creating test/test_helper.exs
* creating test/utilities_test.exs

Your Mix project was created successfully.
You can use "mix" to compile it, test it, and more:

    cd utilities
    mix test

Run "mix help" for more commands.


$ mix new datasets

* creating README.md
* creating .gitignore
* creating mix.exs
* creating lib
* creating lib/datasets.ex
* creating test
* creating test/test_helper.exs
* creating test/datasets_test.exs

Your Mix project was created successfully.
You can use "mix" to compile it, test it, and more:

    cd datasets
    mix test

Run "mix help" for more commands.

$ mix new svm

* creating README.md
* creating .gitignore
* creating mix.exs
* creating lib
* creating lib/svm.ex
* creating test
* creating test/test_helper.exs
* creating test/svm_test.exs

Your Mix project was created successfully.
You can use "mix" to compile it, test it, and more:

    cd svm
    mix test

Run "mix help" for more commands.

现在我们项目中的文件结构应该像这样:

$ tree
.
├── README.md
├── apps
│   ├── datasets
│   │   ├── README.md
│   │   ├── lib
│   │   │   └── datasets.ex
│   │   ├── mix.exs
│   │   └── test
│   │       ├── datasets_test.exs
│   │       └── test_helper.exs
│   ├── svm
│   │   ├── README.md
│   │   ├── lib
│   │   │   └── svm.ex
│   │   ├── mix.exs
│   │   └── test
│   │       ├── svm_test.exs
│   │       └── test_helper.exs
│   └── utilities
│       ├── README.md
│       ├── lib
│       │   └── utilities.ex
│       ├── mix.exs
│       └── test
│           ├── test_helper.exs
│           └── utilities_test.exs
├── config
│   └── config.exs
└── mix.exs

当切回 umbrella 项目的根目录时, 可以发现我们可以调用所有常见的命令, 比如: compile(编译). 所有的子项目也是普通的 application,你可以切到他们的目录和通常项目一样做 Mix 可以做的事.

$ mix compile

==> svm
Compiled lib/svm.ex
Generated svm app

==> datasets
Compiled lib/datasets.ex
Generated datasets app

==> utilities
Compiled lib/utilities.ex
Generated utilities app

Consolidated List.Chars
Consolidated Collectable
Consolidated String.Chars
Consolidated Enumerable
Consolidated IEx.Info
Consolidated Inspect

IEx

你也许认为和 umbrella 项目在 IEx 中交互会有些区别. 不管你信不信, 你猜错了! 当我们切到顶层目录并用 iex -S mix 启动 IEx, 我们可以正常的和所有项目进行交互. 让我们改变一下 apps/datasets/lib/datasets.ex 的内容来举个例子:

defmodule Datasets do
  def hello do
    IO.puts("Hello, I'm the datasets")
  end
end
$ iex -S mix
Erlang/OTP {{ site.erlang.OTP }} [erts-{{ site.erlang.erts }}] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

==> datasets
Compiled lib/datasets.ex
Consolidated List.Chars
Consolidated Collectable
Consolidated String.Chars
Consolidated Enumerable
Consolidated IEx.Info
Consolidated Inspect
Interactive Elixir ({{ site.elixir.version }}) - press Ctrl+C to exit (type h() ENTER for help)

iex> Datasets.hello
Hello, I'm the datasets
:ok
Caught a mistake or want to contribute to the lesson? Edit this lesson on GitHub!