关于 elixir-phoenix
elixir-phoenix 是面向 Phoenix 项目的配置技能,采用 Bun、Tailwind v4、devenv 和 PostgreSQL。它提供资源构建、数据库连接、运行时二进制文件及显式执行端到端测试的配置模式。
主要功能
- 01配置 Bun 替代 esbuild
- 02设置 Tailwind v4 资源工作流
- 03配置 devenv 和 PostgreSQL
- 04通过 NODE_PATH 解析 Phoenix JavaScript 依赖
- 05配置运行时二进制文件路径
- 06将端到端测试设为手动执行
适用场景
- 01创建使用 PostgreSQL 的 Phoenix 项目
- 02配置 Bun 和 Tailwind 资源构建
- 03使用 devenv 设置本地开发环境
- 04仅在明确要求时运行端到端测试
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ gsmlg-dev/ code-agent --skill elixir-phoenix安装后在 Claude Code 中输入/elixir-phoenix确认已加载。
附带文件references/devenv-template.md
详细介绍
Phoenix 项目设置
使用 Bun、Tailwind v4、devenv 和 PostgreSQL 的 Phoenix 项目标准模式。
1. 创建 Phoenix 项目
# Standard project
mix phx.new my_app --database postgres
# Umbrella app
mix phx.new my_app --umbrella --database postgres
生成后,将默认的 esbuild 配置替换为 bun。
2. 将 esbuild 替换为 Bun
在 mix.exs 的 deps 中,将 {:esbuild, ...} 替换为:
{:bun, "~> 1.4", runtime: Mix.env() == :dev},
{:tailwind, "~> 0.2", runtime: Mix.env() == :dev},
在 config/config.exs 中,将 config :esbuild 代码块替换为:
config :bun,
version: "1.3.4",
my_app: [
args: ~w(build assets/js/app.js --outdir=priv/static/assets --external /fonts/* --external /images/*),
cd: Path.expand("../", __DIR__)
]
config :tailwind,
version: "4.1.11",
my_app: [
args: ~w(--input=assets/css/app.css --output=priv/static/assets/app.css),
cd: Path.expand("../", __DIR__)
]
对于 umbrella 应用,将 Path.expand("../apps/my_app", __DIR__) 用于 cd:。
在 config/dev.exs 中,更新 watchers:
watchers: [
tailwind: {Tailwind, :install_and_run, [:my_app, ~w(--watch)]},
bun: {Bun, :install_and_run, [:my_app, ~w(--sourcemap=inline --watch)]}
]
更新 mix.exs 别名:
"assets.deploy": [
"phx.digest.clean",
"tailwind my_app --minify",
"bun my_app --minify",
"phx.digest"
]
3. 设置 NODE_PATH 以解析 Phoenix 依赖
将 NODE_PATH 设置为项目根目录的 deps/ 目录,以便 Bun 从 Phoenix 的 deps/ 目录解析 Node 风格的包。像 import {Socket} from "phoenix" 和 import "phoenix_html" 这样的导入会解析到 Elixir 依赖包,无需 node_modules/。
在 devenv.nix 中,已使用绝对路径完成配置:
env.NODE_PATH = "${config.git.root}/deps";
对于非 devenv 设置,请在 shell 或构建脚本中导出该变量:
export NODE_PATH="$(pwd)/deps"
无需 npm install 或符号链接——Phoenix 会将 JS 与 Elixir 源代码一起放在 deps/<package>/priv/static/ 中。
5. 配置 runtime.exs 以使用二进制文件路径
在 config/runtime.exs 中读取环境变量,以使用 devenv 提供的二进制文件,而不是下载副本。两个包都需要显式配置:
if System.get_env("MIX_BUN_PATH") do
config :bun, path: System.get_env("MIX_BUN_PATH")
end
if System.get_env("MIX_TAILWIND_PATH") do
config :tailwind, path: System.get_env("MIX_TAILWIND_PATH")
end
设置 path 后,hex 包会跳过下载,直接使用提供的二进制文件。devenv 通过 lib.getExe 设置这些环境变量,指向 Nix store 路径(参见第 4 步)。
6. 设置 devenv
完整的 devenv.yaml 和 devenv.nix 模板请参见 references/devenv-template.md。
要点:
lib.getExe会解析MIX_BUN_PATH和MIX_TAILWIND_PATH的 Nix store 路径- PostgreSQL 仅通过 Unix socket 运行(
listen_addresses = "")——不会发生端口冲突 DATABASE_URL使用?socket=参数指向 devenv 的状态目录- 设置
PGHOST,以便psql和 Ecto 自动找到 socket
7. 配置 Ecto 使用基于 URL 的连接
在 config/dev.exs 中,同时支持 Unix socket(devenv)和 TCP(手动设置):
db_config =
[
username: System.get_env("POSTGRES_USER", "my_app_dev"),
password: System.get_env("POSTGRES_PASSWORD", "my_app_dev"),
database: System.get_env("POSTGRES_DB", "my_app_dev"),
show_sensitive_data_on_connection_error: true,
pool_size: 10
]
|> then(fn config ->
case System.get_env("PGHOST") do
nil ->
config ++ [hostname: System.get_env("POSTGRES_HOST", "localhost"),
port: String.to_integer(System.get_env("POSTGRES_PORT", "5432"))]
pghost when is_binary(pghost) ->
if String.starts_with?(pghost, "/") do
config ++ [socket_dir: pghost]
else
config ++ [hostname: pghost,
port: String.to_integer(System.get_env("POSTGRES_PORT", "5432"))]
end
end
end)
config :my_app, MyApp.Repo, db_config
这会自动检测 PGHOST 是 Unix socket 路径还是主机名。
8. 通过 URL 配置生产数据库
在生产环境的 config/runtime.exs 中:
if config_env() == :prod do
database_url =
System.get_env("DATABASE_URL") ||
raise "DATABASE_URL is not set"
config :my_app, MyApp.Repo,
url: database_url,
pool_size: String.to_integer(System.get_env("POOL_SIZE", "10"))
end
9. 端到端测试
端到端测试位于标准 test/ 文件夹旁的 e2e_test/ 中。运行这些测试成本较高,绝不能自动运行——只能在明确请求时运行。
在 mix.exs 中添加 test.e2e 别名:
defp aliases do
[
# ... existing aliases ...
"test.e2e": ["run --no-halt", "cmd mix test e2e_test/"]
]
end
在 mix.exs 项目配置中将 e2e_test/ 配置为额外测试路径,让 Mix 能找到辅助文件,但要将其排除在默认的 mix test 运行之外:
def project do
[
# ...
test_paths: ["test"],
elixirc_paths: elixirc_paths(Mix.env()),
]
end
显式运行端到端测试:
mix test.e2e
绝不要将
test.e2e添加到 CI 流水线、提交前钩子,或任何会在常规构建或测试流程中运行的自动化别名中。
快速参考
| 工具 | Hex 包 | 环境变量 | devenv 来源 |
|---|---|---|---|
| Bun | {:bun, "~> 1.4"} | MIX_BUN_PATH | lib.getExe pkgs.bun |
| Tailwind | {:tailwind, "~> 0.2"} | MIX_TAILWIND_PATH | lib.getExe pkgs.tailwindcss_4 |
| PostgreSQL | {:ecto_sql, ...} + {:postgrex, ...} | DATABASE_URL / PGHOST | services.postgres |