この記事は「Elixir Advent Calendar 2023 9日目の記事です
piyoyo_exのMotzです。
普段はTypeScript,React,Go,Pythonなどを書くことが多いです。
今回Elixirに入門してPhoenixで簡単なSPAを作成したので、その際の開発体験や感想を共有できればと思います。
Elixir,Phoenixについて
Elixir
Elixir (エリクサー) は並行処理の機能や関数型といった特徴を持つ、Erlangの仮想マシン (BEAM) 上で動作するコンピュータプログラミング言語である。ElixirはErlangで実装されているため、分散システム、耐障害性、ソフトリアルタイムシステム等の機能を使用することができるが、拡張機能として、マクロを使ったメタプログラミング、そしてポリモーフィズムなどのプログラミング・パラダイムもプロトコルを介して実装されている
wikipedia Elixir
並行処理、関数型、分散システム、メタプログラミング...なにやら好奇心をそそられる単語が並んでいますね🤔
そして登場時期は2012年 新しいです!
Phoenix
Phoenixは、「開発者の高い生産性」と「高いアプリケーションパフォーマンス」を両立します。 また、リアルタイム機能を実装するためのチャネルや、非常に高速なプリコンパイル済みテンプレートなど、いくつかの興味深い新しい工夫が施されています。
Phoenix v1.6 hexdocs 日本語訳
開発生産性とパフォーマンスの両立とは夢が詰まってますね🥳
現在Elixir Advent Calendar 2023も盛りあがっています!
動作環境
Elixirは1.15.7,Poenixは1.7.10を使用しています。
elixir -v
#Elixir 1.15.7 (compiled with Erlang/OTP 26)
{:phoenix, "~> 1.7.10"},
Hello Phoenix !
今回はDBの設定や起動の手間を省くためにやSqlite3を使用しますが、Postgres、Mysqlを使用する場合は以下のガイドを参考してください。
sqlite3を使用する場合
mix phx.new <アプリ名>
でPhoenixでphoenixアプリケーションを作成できます。以下実行例
mix phx.new hello
* creating hello/lib/hello/application.ex
* creating hello/lib/hello.ex
* creating hello/lib/hello_web/controllers/error_json.ex
~~~~~~~~~~~~~~~~~~略~~~~~~~~~~~~~~~~~~~~~~
* extracting hello/assets/vendor/heroicons/optimized
Fetch and install dependencies? [Yn] Y
* running mix deps.get
* running mix assets.setup
* running mix deps.compile
We are almost there! The following steps are missing:
$ cd hello
Then configure your database in config/dev.exs and run:
$ mix ecto.create
Start your Phoenix app with:
$ mix phx.server
You can also run your app inside IEx (Interactive Elixir) as:
$ iex -S mix phx.server
その後は表示されているコマンドを順に実行し、DBのためのファイル作成とサーバを起動します。
cd hello
mix ecto.create
iex -S phx.server #インタラクティブシェルを開きながらサーバーを起動します
起動できたら
http://localhost:4000へアクセスしましょう。
何回やっても初めてのHello Worldはドキドキですよね!
PhoenixでCRUD + SPA
PhoenixのScaffoldingは以下のパターンで使用できます。
mix phx.gen.live <コンテキスト> <スキーマ> <テーブル名> <カラム名>:<型> ...
mix phx.gen.live Accounts User users name:string age:integer
* creating lib/hello_web/live/user_live/show.ex
* creating lib/hello_web/live/user_live/index.ex
* creating lib/hello_web/live/user_live/form_component.ex
* creating lib/hello_web/live/user_live/index.html.heex
* creating lib/hello_web/live/user_live/show.html.heex
* creating test/hello_web/live/user_live_test.exs
* creating lib/hello/accounts/user.ex
* creating priv/repo/migrations/20231208193941_create_users.exs
* creating lib/hello/accounts.ex
* injecting lib/hello/accounts.ex
* creating test/hello/accounts_test.exs
* injecting test/hello/accounts_test.exs
* creating test/support/fixtures/accounts_fixtures.ex
* injecting test/support/fixtures/accounts_fixtures.ex
Add the live routes to your browser scope in lib/hello_web/router.ex:
live "/users", UserLive.Index, :index
live "/users/new", UserLive.Index, :new
live "/users/:id/edit", UserLive.Index, :edit
live "/users/:id", UserLive.Show, :show
live "/users/:id/show/edit", UserLive.Show, :edit
Remember to update your repository by running migrations:
$ mix ecto.migrate
phx.gen.liveの結果に記述の通りlib/hello_web/router.ex
ファイルを編集して、migrateしましょう。
~~~~~~~
pipeline :api do
plug :accepts, ["json"]
end
scope "/", HelloWeb do
pipe_through :browser
live "/users", UserLive.Index, :index
live "/users/new", UserLive.Index, :new
live "/users/:id/edit", UserLive.Index, :edit
live "/users/:id", UserLive.Show, :show
live "/users/:id/show/edit", UserLive.Show, :edit
get "/", PageController, :home
end
~~~~~~~
mix ecto.migrate
phx server
ここまで実行すればhttp://localhost:4000/users
にアクセスしましょう。心ゆくまでSPAを堪能してください
Elixir + Phoenixのここがスゴイ
主に開発していて良いと感じた部分です。Elixirの並行処理や高可用性などパフォーマンスに関する非機能要件は含んでいません(ここも良いらしい)。
- mixが標準搭載: 他の言語ではパッケージ管理ツールが別になっているものも多いですよね。特にnpm、pipなどで入門者はつまづきがちですよね。
- Phoenix LiveView: リアルタイムなWeb UI を作成できるPhoenixの機能です。Webosocketプロトコルを使用しているので一般的にhttpよりも少ないヘッダーで通信できます。フロントでの記述量を大幅に減らすことができて最高です⚙️。
- Scaffolding: Railsにもあるやつです。簡単なコマンドで基本的なCRUD操作のためのコードを自動生成できます。先ほどのようにLiveViewを使用したSPAまで生成できちゃいます
- hexdocsが整備されてて見やすい: パッケージのドキュメントが掲載されるページです。パッケージの公式ページで見やすいものってあまり無いですよね。特にpipとnpm
- Phoenixのホットリロード: モダンなWebフレームワークでは標準だけど、やっぱり有り難い。さらに簡単にインタラクティブシェルを立ち上げられるので関数の動作確認するときなどとても便利!
-
美しい文法:パイプや関数パターンマッチング、関数の呼び出し方など書いていて楽しいです🤗
まだあまり詳しくないですが、学習意欲を掻き立てられますね! - Tailwind CSSがインストール済み: 皆さん好きですよね、デファクト化しつつあると思います。
Phoenixを使用した感想
LiveViewを初めとした革新的な新機能を導入しながら、細かい部分の使い心地も非常に良かったです。
こまれまでのフレームワークやエコシステムのいい点を取り込みつつ、煩わしさが取り除かれており面白くて、丁寧なフレームワークという印象でした。
Tips
github hero iconsをassetsに入れない方法
git init .
するとやたら多くのファイルが作成されていてビックリするかもしれません。
主にheroiconsのCSVが原因です。CSVということもあり特にサイズが大きいくももないので、Githubにそのままpushしても構いません。
余分なファイルがコミットされるのが嫌な方(自分もそうでした)はassets/heroiconsを削除して、mix.exとmix.exsを書き換えることで、githubに余分なファイルをpushせずに済みます
他のelxirパッケージが保存されている /depsにheroiconsも保存されます。
rm -r ./assets/vendor/heroicons
assets/tailwind.config.js
- let iconsDir = path.join(__dirname, "./vendor/heroicons/optimized")
+ let iconsDir = path.join(__dirname, "../deps/heroicons/optimized")
~~~~~~~
defp deps do
[
{:phoenix, "~> 1.7.10"},
{:phoenix_ecto, "~> 4.4"},
{:ecto_sql, "~> 3.10"},
{:ecto_sqlite3, ">= 0.0.0"},
{:phoenix_html, "~> 3.3"},
{:phoenix_live_reload, "~> 1.2", only: :dev},
{:phoenix_live_view, "~> 0.20.1"},
{:heroicons,
github: "tailwindlabs/heroicons",
tag: "v2.0.18",
app: false,
compile: false,
sparse: "optimized"},
~~~~~~~
]
end
~~~~~~~
ビューにheroiconsを使用するコードを追加して動作を確認しましょう
+ <.icon name="hero-star" class="w-16 h-16" />
mix deps.get
mix phx.servcer
最新のPhoenixの更新でオプションとして追加されたようです
開発コミュニティが活発そうでいいですね~🥰
参考文献