当我们通过 mix phx.new
命令生成一个新的Phoenix应用时,它会创建以下目录结构:
├── _build
├── assets
├── config
├── deps
├── lib
│····├── hello
│····├── hello.ex
│····├── hello_web
│····└── hello_web.ex
├── priv
└── test
我们一个一个来看:
_build
编译结果存放目录,不应该放入版本控制,可以被随时删除,删除后Mix会重新编译项目。assets
前端资源存放目录,如JavaScript和CSS。这些资源会自动被 esbuild
打包。图片和字体等静态文件放在 priv/static
目录。config
项目配置目录。 config/config.exs
文件是配置的入口,该文件的最后会引入特定环境的配置,具体指 config/dev.exs
, config/test.exs
和 config/prod.exs
。最后执行的是 config/runtime.exs
,这里也是放置密码和其他动态配置的最佳位置。deps
依赖存放目录。所有 mix.exs
文件中的 deps
函数列举的依赖都放在该目录下。该目录也不应该放入版本控制,而且可以随时删除。删除后会强制Mix重新下载依赖。lib
应用源码目录。下面包含两个 hello
和 hello_web
两个子目录。 hello
目录下是业务逻辑和业务领域,会直接与数据库交互,是MVC中的M。 hello_web
负责展示业务领域,这里是通过网页,是MVC中的VC。priv
存放非源码的资源文件。你可以将数据库脚本,翻译文件,图片等放在这里。 assets
目录下的文件生成的资源默认存放在 priv/static/assets
下。test
测试目录,目录结构通常与 lib
目录一致。lib/hello
目录业务领域都在 lib/hello
目录下,因为我们的项目没有业务逻辑,所以目录空空荡荡,只有下面三个文件:
lib/hello
├── application.ex
├── mailer.ex
└── repo.ex
lib/hello/application.ex
文件定义了一个名为 Hello.Application
的Elixir应用,因为Phoenix应用本质上就是一个Elixir应用。Hello.Application
模块定义了应用包含哪些服务:
children = [
# Start the Telemetry supervisor
HelloWeb.Telemetry,
# Start the Ecto repository
Hello.Repo,
# Start the PubSub system
{Phoenix.PubSub, name: Hello.PubSub},
# Start the Endpoint (http/https)
HelloWeb.Endpoint
# Start a worker by calling: Hello.Worker.start_link(arg)
# {Hello.Worker, arg}
]
如果这是你第一次接触Phoenix,先不用关注细节。简单来说就是应用启动了一个数据仓库,一个用于在进程和节点之间共享消息的发布订阅系统,以及一个高效处理HTTP请求的端点。这些服务按定义的顺序启动,关闭时按相反的顺序停止。
lib/hello/mailer.ex
文件定义了 Hello.Mailer
模块,提供了发送邮件的接口:
defmodule Hello.Mailer do
use Swoosh.Mailer, otp_app: :hello
end
在 lib/hello
目录下,还有一个 lib/hello/repo.ex
文件。它定义了 Hello.Repo
模块,是我们访问数据库的接口。如果你使用的是Postgres(默认数据库),你可以看到下面的代码:
defmodule Hello.Repo do
use Ecto.Repo,
otp_app: :hello,
adapter: Ecto.Adapters.Postgres
end
目前就是这样,随着我们继续开发,会往该目录添加文件和模块。
lib/hello_web
目录lib/hello_web
目录里是和网页相关的部分,目录结构如下:
lib/hello_web
├── controllers
│·····├── page_controller.ex
│·····├── page_html.ex
│·····├── error_html.ex
│·····├── error_json.ex
│·····└── page_html
│···········└── home.html.heex
├── components
│·····├── core_components.ex
│·····├── layouts.ex
│·····└── layouts
│···········├── app.html.heex
│···········└── root.html.heex
├── endpoint.ex
├── gettext.ex
├── router.ex
└── telemetry.ex
当前 controllers
和 components
目录下的所有文件都是为了创建例子中的欢迎页。
乍一看这两个目录,Phoenix提供了控制布局,HTML和错误页面。
除了上面提到的目录, lib/hello_web
根目录下还有4个文件。 lib/hello_web/endpoint.ex
是HTTP请求的入口。当浏览器访问http://localhost:4000时,端点开始处理数据,最后到达 lib/hello_web/router.ex
中定义的路由器。路由器将请求分发到控制器,控制器调用视图模块将HTML页面渲染到客户端。
通过监控,Phoenix能够收集和发送应用监控指标。 lib/hello_web/telemetry.ex
文件定义了处理指标检测的监控进程。
最后, lib/hello_web/gettext.ex
文件通过Gettext提供了国际化功能。如果你并不关心国际化,可以跳过该文件。
assets
目录assets
目录包含前端相关的源代码,如Javascript和CSS。从Phoenix v1.6开始,我们使用esbuild来打包资源,esbuild已整合进你的app,相关配置见 config/config.exs
文件。
静态资源被放在 priv/static
目录下,生成的资源放在 priv/static/assets
下。 priv/static
目录下的文件都由 lib/hello_web/endpoint.ex
文件中配置的 Plug.Static
插件提供服务。在开发模式(MIX_ENV=dev
)下,Phoenix会监视 assets
目录的变化,并自动更新浏览器的前端页面。
注意,当你使用 mix [phx.new](http://phx.new)
创建Phoenix应用时,可以通过一些选项来影响 assets
目录的布局和存在。事实上Phoenix可以自定义前端工具或者没有前端(例如API应用)。
如果默认的esbuild不能满足你的需求,例如你想使用另一个构建工具,可以选择自定义资源构建。
对于CSS,Phoenix使用的是Tailwind CSS框架,你也可以选择其他CSS框架。