どうも、靖宗です。
今回はMix Tasksということでmix phx.hogehoge
のコマンドあたりの説明でしょうか。
Mix Tasks
Phoenix Specific Mix Tasks
Phoenixで使いそうなコマンド一覧があります。
mix local.phx # Updates the Phoenix project generator locally mix phx # Prints Phoenix help information mix phx.digest # Digests and compresses static files mix phx.digest.clean # Removes old versions of static assets. mix phx.gen.cert # Generates a self-signed certificate for HTTPS testing mix phx.gen.channel # Generates a Phoenix channel mix phx.gen.context # Generates a context with functions around an Ecto schema mix phx.gen.embedded # Generates an embedded Ecto schema file mix phx.gen.html # Generates controller, views, and context for an HTML resource mix phx.gen.json # Generates controller, views, and context for a JSON resource mix phx.gen.presence # Generates a Presence tracker mix phx.gen.schema # Generates an Ecto schema and migration file mix phx.gen.secret # Generates a secret mix phx.new # Creates a new Phoenix application mix phx.new.ecto # Creates a new Ecto project within an umbrella project mix phx.new.web # Creates a new Phoenix web project within an umbrella project mix phx.routes # Prints all routes mix phx.server # Starts applications and their servers
細かい機能はPhoenix公式ドキュメントの「MIX TASKS」を見れば良さそうです。
幾つか簡単に取り上げてくれているので、一応目を通しておきます。
mix phx.new
言わずと知れたPhoenixプロジェクトを生成する際に使うコマンドです。
--no-ecto
や--no-webpack
というオプションをつける事でEctoの実装を無くしたり、Webpackの実装を無くしたりできるそうですが、基本的には必要なんじゃないでしょうか。
(APIサーバーとして機能するときはWebpackは不要?)
実際に生成するプロジェクト名はスネークケースがいいっぽいです。
> mix phx.new task_tester
> mix phx.new ../task_tester > mix phx.new /Users/me/work/task_tester
mix phx.new
でプロジェクトを生成するとアプリケーション名はプロジェクト名(上記だとtask_tester
)になります。
もしアプリケーション名を変更したい場合はmix phx.new task_tester --app hello
と--app
オプションを利用するそうです。
mix.exs
でアプリケーション名が変更されています。
defmodule Hello.MixProject do use Mix.Project def project do [app: :hello, version: "0.1.0", ...
このアプリケーション名を変更するとモジュール名などの接頭辞が変わるようです。
defmodule HelloWeb.PageController do use HelloWeb, :controller ...
--app
オプションでhello
を設定したのでモジュール名がHello
から始まってます。
lib/
フォルダ以下のディレクトリやファイル名なども変わります。
基本は--app
でいいような気はしますが、「モジュール名の接頭辞だけ変えたい!」という場合には--module
オプションで指定出来るようです。
$ mix phx.new task_tester --module Hello * creating task_tester/config/config.exs * creating task_tester/config/dev.exs * creating task_tester/config/prod.exs * creating task_tester/config/prod.secret.exs * creating task_tester/config/test.exs * creating task_tester/lib/task_tester/application.ex * creating task_tester/lib/task_tester.ex * creating task_tester/lib/task_tester_web/channels/user_socket.ex * creating task_tester/lib/task_tester_web/views/error_helpers.ex * creating task_tester/lib/task_tester_web/views/error_view.ex * creating task_tester/lib/task_tester_web/endpoint.ex * creating task_tester/lib/task_tester_web/router.ex * creating task_tester/lib/task_tester_web.ex * creating task_tester/mix.exs * creating task_tester/README.md * creating task_tester/.gitignore * creating task_tester/test/support/channel_case.ex * creating task_tester/test/support/conn_case.ex * creating task_tester/test/test_helper.exs * creating task_tester/test/task_tester_web/views/error_view_test.exs * creating task_tester/lib/task_tester_web/gettext.ex * creating task_tester/priv/gettext/en/LC_MESSAGES/errors.po * creating task_tester/priv/gettext/errors.pot * creating task_tester/lib/task_tester/repo.ex
mix.exs
は下のようなかんじ。
defmodule Hello.MixProject do use Mix.Project def project do [app: :task_tester, ...
アプリケーション名はtask_tester
のままで、接頭辞のみがHello
となっています。
ややこしいことになりそうなので、変えたいなら--app
を使った方が良さそうです。
mix phx.gen.html
これはContextあたりで使いました。HTMLでのresource
(router.ex
でresource
指定する奴)を生成する際に便利なコマンドです。
Webレイヤーの実装(コントローラ、ビュー、テンプレート)はもちろん、EctoのマイグレーションファイルやContextも生成してくれます。
このコマンドは引数が多くてややこしいですが、その中身は至ってシンプルで
mix phx.gen.html Context名 スキーマ名 リソース名 スキーマのリスト(項目名:型)
です。
$ mix phx.gen.html Blog Post posts body:string word_count:integer * creating lib/hello_web/controllers/post_controller.ex * creating lib/hello_web/templates/post/edit.html.eex * creating lib/hello_web/templates/post/form.html.eex * creating lib/hello_web/templates/post/index.html.eex * creating lib/hello_web/templates/post/new.html.eex * creating lib/hello_web/templates/post/show.html.eex * creating lib/hello_web/views/post_view.ex * creating test/hello_web/controllers/post_controller_test.exs * creating lib/hello/blog/post.ex * creating priv/repo/migrations/20170906150129_create_posts.exs * creating lib/hello/blog/blog.ex * injecting lib/hello/blog/blog.ex * creating test/hello/blog/blog_test.exs * injecting test/hello/blog/blog_test.exs
mix
系のコマンドに一般的に言えることですが、次に何やったらいいか注釈がでてくれます。
Add the resource to your browser scope in lib/hello_web/router.ex: resources "/posts", PostController Remember to update your repository by running migrations: $ mix ecto.migrate
ルーティングの設定とマイグレーションしろよ!と出ています。基本これだけでリソースが作成できます。
大体無いとは思うんですが、Contextいらないよ!って時(Bootstrapのテストなど、なんらかのテストに使う?)は--no-context
というオプションがあるそうです。
活用法があまり思い浮かばないので省略。
同様に--no-schema
オプションもあり。
mix phx.gen.json
こちらは使ったことはないですが、見た目からして上記のJSON版といったところでしょうか。
$ mix phx.gen.json Blog Post posts title:string content:string * creating lib/hello_web/controllers/post_controller.ex * creating lib/hello_web/views/post_view.ex * creating test/hello_web/controllers/post_controller_test.exs * creating lib/hello_web/views/changeset_view.ex * creating lib/hello_web/controllers/fallback_controller.ex * creating lib/hello/blog/post.ex * creating priv/repo/migrations/20170906153323_create_posts.exs * creating lib/hello/blog/blog.ex * injecting lib/hello/blog/blog.ex * creating test/hello/blog/blog_test.exs * injecting test/hello/blog/blog_test.exs
コマンドの仕様もほぼhtml
と変わらないようです。
コマンド実行後の注釈はちょっと変わってきています。
Add the resource to your :api scope in lib/hello_web/router.ex: resources "/posts", PostController, except: [:new, :edit] Remember to update your repository by running migrations: $ mix ecto.migrate
:new
と:edit
のアクションを除外しています。
JSONなので新規生成画面と編集画面がないためでしょう。HTTPリクエストなどで直接:create
や:update
を実行するということでしょう。
htmlと同様に--no-context
と--no-schema
オプションもあり。
mix phx.gen.context
Contextの章でAccountsにCredentialを追加するときに使いました。
追加するように使った場合はinjecting lib/hello/accounts.ex
というように既存のContextに追記する形で生成されましたが、Contextのみ生成したい場合にも利用できるようです。
主な使用方法はhtml
やjson
の時と同じ。
$ mix phx.gen.context Accounts User users name:string age:integer * creating lib/hello/accounts/user.ex * creating priv/repo/migrations/20170906161158_create_users.exs * creating lib/hello/accounts/accounts.ex * injecting lib/hello/accounts/accounts.ex * creating test/hello/accounts/accounts_test.exs * injecting test/hello/accounts/accounts_test.exs
mix phx.gen.schema
HTMLやJSONのリソースも作らず、Contextも不要というレアケース用?でもコマンドが用意されてるってことは必要なタイミングがあるのかも。
コマンド引数はhtml
やjson
からContext名を省略したようなかんじ。
$ mix phx.gen.schema Accounts.Credential credentials email:string:unique user_id:references:users * creating lib/hello/accounts/credential.ex * creating priv/repo/migrations/20170906162013_create_credentials.exs
mix phx.gen.channel
Channelを生成するためのコマンド。Channelの章では手動で作成しましたが、コマンドでも生成してくれるようです。
引数は純粋にチャンネル名のみ。
$ mix phx.gen.channel Room * creating lib/hello_web/channels/room_channel.ex * creating test/hello_web/channels/room_channel_test.exs
ちゃんとメッセージも出してくれます。
Add the channel to your `lib/hello_web/channels/user_socket.ex` handler, for example: channel "rooms:lobby", HelloWeb.RoomChannel
mix phx.gen.presence
これはPresenceの章で使いました。
一応モジュール名を指定できますが、省略すればPresence
で作成されます。
$ mix phx.gen.presence * creating lib/hello_web/channels/presence.ex
こちらもきちんと注釈を付けてくれます。
Add your new module to your supervision tree, in lib/hello/application.ex: children = [ ... HelloWeb.Presence ] You're all set! See the Phoenix.Presence docs for more details: http://hexdocs.pm/phoenix/Phoenix.Presence.html
mix phx.routes
Routingの章で利用しました。
コマンドを実行すればルーティングルールが表示されます。
$ mix phx.routes page_path GET / TaskTester.PageController.index/2
ルーティングファイルが2個以上あるときは、ルーティングファイル名を指定するとソイツだけみれるようです。
$ mix phx.routes TaskTesterWeb.Router page_path GET / TaskTesterWeb.PageController.index/2
mix phx.server
サーバーを立ち上げるコマンド。DoesNotExist
オプションとかもあるけどよくわかんない。(本来は「DoesNotExist」が必要だけど省略されてる?)
iexで立ち上げたい時はiex -S mix phx.server
を実行してやればよいそうで。
$ iex -S mix phx.server Erlang/OTP 17 [erts-6.4] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false] [dtrace] [info] Running TaskTesterWeb.Endpoint with Cowboy on port 4000 (http) Interactive Elixir (1.0.4) - press Ctrl+C to exit (type h() ENTER for help) iex(1)>
これ地味に便利そうですね。
mix phx.digest
静的ファイル(static assets)の名前にダイジェスト(MD5)を付与し、圧縮するコマンドだそうです。
機能的にほぼデプロイ用(改ざん防止、転送量軽減)と考えて問題無さそうです。
assets/
ディレクトリにあるファイルに処理を行い、デフォルトではpriv/static
にコピーするようです。
出力されるファイルの場所や処理するファイルの場所を指定したいときは引数で調整可能。
$ mix phx.digest priv/static -o www/public Check your digested files at 'www/public'.
コンフィグに:
を指定すると圧縮するファイルの対象を変更できるようです。
config :phoenix, :gzippable_exts, ~w(.js .css)
役割的にconfig/config.exs
あたりにでも書けば良いのでしょうか。
デプロイは別の章でやるので、そのときにもう一度確認します。
飛ばし飛ばしやってるつもりが結構長くなったのでまた次回!