Posted at

Elixir/Phoenix+Angularで環境構築

最近 angular に触る機会があり、Phoenixで一緒に開発できないかなーと思って少し試してみました。


環境


  • Elixir : 1.6.4 (compiled with OTP 20)

  • phoenix : 1.3.4

  • Node : v8.9.3

  • Angular CLI: 7.0.2


Phoenixプロジェクトの作成

$ mix phx.new ng_phx --no-brunch --no-html

JSのビルドツールであるbrunchとhtmlは作成しないようにします


Angular-CLIでプロジェクト作成

$ cd ng_phx

$ ng new web

Phoenixプロジェクトの中にangularのプロジェクトを作成します

angular-cliに聞かれる内容はお好みで。


config/dev.exsを編集

watchersのところを以下のようにします


config/dev.exs

   debug_errors: true,

code_reloader: true,
check_origin: false,
- watchers: []
+ watchers: [
+ ng: ["build", "--watch", "--output-path=../priv/static/web", "--base-href=/web/", cd: Path.expand("../web/", __DIR__)]
+ ]

# ## SSL Support
#


ビルドの出力先を priv/static/web にしています。

ng buildはビルド前にビルド対象のディレクトリをクリーンしてしまうので

サブディレクトリを一つ追加しています。

またそれに併せて base href の設定も追加しています

ついでに .gitignore/priv/static/web を追加しておきます


.gitignore

 # secrets files as long as you replace their contents by environment

# variables.
/config/*.secret.exs
+
+ # ng build output directory
+/priv/static/web


endpointを編集

angularはSPAとして動くため、 /web/index.html にアクセスしても /web/ に飛ばれされてしまいます。

そのため /web/ でアクセスしても /web/index.htmlにリダイレクトされるように設定を追加します

また priv/static/web 以下に静的ファイルとしてアクセスするために

plug, Plug.Static の only に web を追加します


lib/ng_phx_web/endpoint.ex

 defmodule NgPhxWeb.Endpoint do

use Phoenix.Endpoint, otp_app: :ng_phx

+ def redirect_index(conn = %Plug.Conn{path_info: ["web"]}, _opts) do
+ %Plug.Conn{conn | path_info: ["web", "index.html"]}
+ end
+
+ def redirect_index(conn, _opts) do
+ conn
+ end
+
+ plug :redirect_index
+
socket "/socket", NgPhxWeb.UserSocket

...

# when deploying your static files in production.
plug Plug.Static,
at: "/", from: :ng_phx, gzip: false,
- only: ~w(css fonts images js favicon.ico robots.txt)
+ only: ~w(web css fonts images js favicon.ico robots.txt)



サーバーを起動

ここまで設定すればあとは以下のコマンドを実行すれば、Phoenix上でangularを動かすことができます

$ mix phx.new

ng build に時間がかかるので少し待ちましょう。

http://localhost:4000/web/ にアクセスして angular のロゴが表示されれば成功です :tada:

同一ドメインで起動するので、CORSの問題などはないと思います。

ただし、 ng build の生成物を表示しているだけなので、 browser sync がないのが少しつらいですね・・・

(あと ng build が微妙に遅い)

他にいい方法などありましたら、教えていただけると嬉しいです!

今回のサンプルはいかにあげてあります

https://github.com/tamanugi/ng_phx