当我们通过 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框架。