elixir-phoenix について
elixir-phoenixは、Bun、Tailwind v4、devenv、PostgreSQLを使うPhoenixプロジェクト向けの設定スキルです。アセット、データベース接続、実行時バイナリ、明示的に実行するE2Eテストの設定例をまとめています。
主な機能
- 01esbuildをBunに置き換える設定
- 02Tailwind v4のアセットワークフロー
- 03devenvとPostgreSQLの設定
- 04NODE_PATHによるPhoenix JavaScript依存関係の解決
- 05実行時バイナリパスの設定
- 06E2Eテストを明示実行に限定
活用シーン
- 01PostgreSQLを使うPhoenixプロジェクトの作成
- 02BunとTailwindのアセットビルド設定
- 03devenvによるローカル開発環境の構築
- 04明示的な依頼時のみE2Eテストを実行
インストール
コマンドをコピーしてターミナルで実行します。
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__)
]
アンブレラアプリでは、cd: に Path.expand("../apps/my_app", __DIR__) を使用します。
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. Phoenix の依存関係解決用に NODE_PATH を設定する
Bun が Phoenix の deps/ ディレクトリから Node 形式のパッケージを解決できるよう、NODE_PATH をプロジェクトルートの deps/ ディレクトリに設定します。import {Socket} from "phoenix" や import "phoenix_html" のようなインポートは、node_modules/ がなくても Elixir の依存パッケージに解決されます。
devenv.nix では、絶対パスを使用してすでに設定されています。
env.NODE_PATH = "${config.git.root}/deps";
devenv を使用しない場合は、シェルまたはビルドスクリプトでエクスポートします。
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 ストアのパスを指定します(手順 4 を参照)。
6. devenv をセットアップする
devenv.yaml と devenv.nix のテンプレート全体については、references/devenv-template.md を参照してください。
要点:
lib.getExeがMIX_BUN_PATHとMIX_TAILWIND_PATH用の Nix ストアパスを解決します- PostgreSQL は Unix ソケットのみで実行されます(
listen_addresses = "")。ポートの競合はありません DATABASE_URLは、devenv の状態ディレクトリを指す?socket=パラメーターを使用しますPGHOSTが設定されるため、psqlと Ecto の両方がソケットを自動的に見つけます
7. URL ベースの接続用に Ecto を設定する
config/dev.exs で、Unix ソケット(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 ソケットのパスかホスト名かが自動検出されます。
8. URL を使用した本番データベース
prod 用の 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. エンドツーエンドテスト
E2e テストは標準の test/ フォルダーと並ぶ e2e_test/ に置きます。実行コストが高いため、自動実行は絶対に避けてください。明示的に要求された場合にのみ実行します。
mix.exs に test.e2e エイリアスを追加します。
defp aliases do
[
# ... existing aliases ...
"test.e2e": ["run --no-halt", "cmd mix test e2e_test/"]
]
end
Mix がヘルパーを見つけられるよう、mix.exs のプロジェクト設定で e2e_test/ を追加のテストパスとして設定します。ただし、デフォルトの mix test 実行からは除外します。
def project do
[
# ...
test_paths: ["test"],
elixirc_paths: elixirc_paths(Mix.env()),
]
end
E2e テストを明示的に実行します。
mix test.e2e
通常のビルドまたはテストサイクルの一部として実行される CI パイプライン、コミット前フック、その他の自動実行エイリアスには、
test.e2eを絶対に追加しないでください。
クイックリファレンス
| ツール | 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 |