さてPhoenix Frameworkですが…
Elixir, Phoenix あたりの記事を探しているとTwitterでこんなの見つけました。
Phoenix Framework (Elixir)で React.jsを動かしてみる - Misoca開発ブログ http://tech.misoca.jp/entry/2015/05/21/130456 …
eitoballさん、どうもありがとうございます
Reactもちょっと前の仕事でいじりかけていたのでこれ幸いと試してみました…しかし、実際に手を動かしてみるといくつかハマリポイントがあったので補足しつつ自分用にメモします。
予め入れておくもの
Elixir (当たり前)
Elixirで試しに何か書いてみる(その1)
及びそこから先のリンク先である
Installing Elixir
を参考にしてインストールしてください。同時にElixirの本体(?)であるErlang/OTPとビルドツールmixもインストールされます。
ここはまずハマリポイントはないと思います(あるとしたら古いErlang/OTPが入ってしまっているとかでしょうかね)。
Phoenix Framework
これもないと話になりません。Phoenixの本家サイトからGet started with Phoenixをクリックしてドキュメントを読みつつPhoenix Frameworkをインストールしてください。
ただし、ドキュメントのバージョンによって内容が変わりそうなのでトップページからGet started with Phoenixをクリックするほうがいいと思います。
今回は2015年5月26日時点の最新、v0.13.1に沿って簡単に解説します。
1. パッケージマネージャHexをインストールする
$ mix local.hex
2. Phoenix installerをダウンロードしてmixでインストールする
$ mix archive.install https://github.com/phoenixframework/phoenix/releases/download/v0.13.1/phoenix_new-0.13.1.ez
(やはりバージョンがしょっちゅう変わると思われるので要注意。実は0.12.0では今回のプログラムはphoenix_htmlがインストールされなくて(手動で修正は可能らしい)失敗します。)
node.js
Phoenixはいくつかのnodeベースのコマンドを利用しているのでnode.js(及びnpm)をインストールしておきます。
node.jsについてはインストール、設定ともにあちこちに解説記事があるので代表的なところだけリンクを書きます。
node.js本家
node.js日本ユーザグループ
個人的にはバージョン切り替えにnodebrewを使っているので…
こことかここを参考にしてインストールしてください。手元ではv0.10.38,v0.12.4で動作確認できました。io.jsでも行けそうですが試してません。
bower
bowerはフロントエンド(JavaScript)用のパッケージマネージャです。Phoenixはbowerとビルドツールbrunchに依存していますが、brunchはインストールしてくれるのにbowerはインストールしてくれないので自分でインストールします1。
$ npm install -g bower
でインストール完了。
inotify-tools
ファイル変更検知ツールです。これを入れておかないとinotifywaitがなくて失敗します2。
Ubuntu, Debianは
$ sudo apt-get install inotify-tools
でインストールできます。
mixでプロジェクトを作成する
1. プロジェクトのディレクトリを構成する3。
$ mix phoenix.new react_phoenix
We are all set! Run your Phoenix application:
$ cd react_phoenix
$ mix phoenix.server
You can also run it inside IEx (Interactive Elixir) as:
$ iex -S mix phoenix.server
が表示されればOKです。*running npm install
のところで少し時間がかかります。
2. jqueryとreactのbowerパッケージのインストール
ここは元記事と手順を変えました。
まず1.で作られたディレクトリに移動します。
$ cd react_phoenix
続いてbowerを使う準備をします。
$ bower init
初めてbowerを起動した時だけ
? May bower anonymously report usage statistics to improve the tool over time? (Y/n)
と聞いてきますので、情報収集手伝ってあげるよ!という人はY(またはenter)を押してください。
あとは今回は全部enterでよいです(実はぼくもbowerに全然慣れてないので細かいところがわからなかったのです)。
最後
{
name: 'react_phoenix',
version: '0.0.0',
license: 'MIT',
ignore: [
'**/.*',
'node_modules',
'bower_components',
'test',
'tests'
]
}
? Looks good? (Y/n)
まで表示されたらY(またはEnter)を押して完了。
次に今、生成されたbower.jsonを修正します。
生成されたbower.json
{
"name": "react_phoenix",
"version": "0.0.0",
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
]
}
に依存ライブラリ、jqueryとreactの記述を加えます。
{
"name": "react_phoenix",
"version": "0.0.0",
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
],
"dependencies": {
"jquery": "~2.1.4",
"react": "~0.13.3"
}
}
そしてjqueryとreactをbowerからインストールします。
$ bower install
bower not-cached git://github.com/facebook/react-bower.git#~0.13.3
bower resolve git://github.com/facebook/react-bower.git#~0.13.3
bower not-cached git://github.com/jquery/jquery.git#~2.1.4
bower resolve git://github.com/jquery/jquery.git#~2.1.4
bower download https://github.com/facebook/react-bower/archive/v0.13.3.tar.gz
bower download https://github.com/jquery/jquery/archive/2.1.4.tar.gz
bower extract react#~0.13.3 archive.tar.gz
bower extract jquery#~2.1.4 archive.tar.gz
bower resolved git://github.com/facebook/react-bower.git#0.13.3
bower resolved git://github.com/jquery/jquery.git#2.1.4
bower install react#0.13.3
bower install jquery#2.1.4
インストール完了。
ディレクトリの状態
さて、ここでディレクトリがどうなっているか確認しておきましょう。
your_host:~/react_phoenix$ ls
bower.json _build deps mix.exs node_modules priv test
brunch-config.js config lib mix.lock package.json README.md web
ここのweb以下にファイルを書き足していきます。
web以下はこんな感じになっています。
web
├── channels
├── controllers
│ └── page_controller.ex
├── models
├── router.ex
├── static
│ ├── css
│ │ └── app.scss
│ ├── js
│ │ └── app.js
│ └── vendor
│ └── phoenix.js
├── templates
│ ├── layout
│ │ └── application.html.eex
│ └── page
│ └── index.html.eex
├── views
│ ├── error_view.ex
│ ├── layout_view.ex
│ └── page_view.ex
└── web.ex
表示用のコントローラとビューを追加する(reactは後から追加する)
またmisocaブログに戻りましょう。
1. コントローラを記述
web/controllers/hello_world_controller.ex
を以下のように作成します。
defmodule ReactPhoenix.HelloWorldController do
use ReactPhoenix.Web, :controller
plug :action
def index(conn, _params) do
render conn, "index.html"
end
end
:controller
はElixirのatomです。またReactPhoenix.WebでWは大文字です。最初typoして間違い探しに手間取りました。
2. ビューを記述
同じように web/views/hello_world_view.ex
を以下のように作成します。
defmodule ReactPhoenix.HelloWorldView do
use ReactPhoenix.Web, :view
end
3. テンプレートを作成
まずディレクトリをひとつ作成。
$ mkdir web/templates/hello_world
そして以下の内容でファイル web/templates/hello_world/index.html.eex
(拡張子がhtml.eex)を作成します。
<h2>HelloWorld#index</h2>
4. ルーター(router)の設定
Webのディレクトリと参照先を管理しているrouterを設定します。このへんはrailsとかsinatraとかと同じですね。web/router.exに1行追加して
defmodule ReactPhoenix.Router do
use ReactPhoenix.Web, :router
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_flash
plug :protect_from_forgery
end
pipeline :api do
plug :accepts, ["json"]
end
scope "/", ReactPhoenix do
pipe_through :browser # Use the default browser stack
get "/", PageController, :index
# 次の1行を追加する
get "/hello_world", HelloWorldController, :index
end
# Other scopes may use custom stacks.
# scope "/api", ReactPhoenix do
# pipe_through :api
# end
end
5. サーバーを実行する
$ iex -S mix phoenix.server
すると初回だけいろいろビルドします…(その後はもし依存関係が変わっていたり、内容が更新されていた場合に必要な物だけビルドされます)
Erlang/OTP 17 [erts-6.4] [source] [64-bit] [async-threads:10] [hipe] [kernel-poll:false]
==> poolboy (compile)
Compiled src/poolboy_worker.erl
Compiled src/poolboy_sup.erl
Compiled src/poolboy.erl
==> decimal
Compiled lib/decimal.ex
Generated decimal app
==> poison
Compiled lib/poison.ex
Compiled lib/poison/decoder.ex
Compiled lib/poison/parser.ex
Compiled lib/poison/encoder.ex
Generated poison app
==> ranch (compile)
Compiled src/ranch_transport.erl
Compiled src/ranch_acceptors_sup.erl
Compiled src/ranch.erl
Compiled src/ranch_app.erl
Compiled src/ranch_protocol.erl
...
(中略)
...
Generated react_phoenix app
[info] Running ReactPhoenix.Endpoint with Cowboy on port 4000 (http)
Interactive Elixir (1.0.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> [BABEL] Note: The code generator has deoptimised the styling of "bower_components/jquery/dist/jquery.js" as it exceeds the max of "100KB".
[info] GET /
[info] Processing by ReactPhoenix.PageController.index/2
Parameters: %{"format" => "html"}
Pipelines: [:browser]
...
まで来たらサーバー起動完了です。
http://localhost:4000
などで実際にアクセスしてみましょう。
↑このように表示が出たらとりあえず成功です。
Reactを使ってみる
1. テンプレートファイルを書き換える。
テンプレートファイル web/templates/hello_world/index.html.eex
を次のように書き換えます。
<div id="hello_world"></div>
2. JavaScriptファイルをReactで書き換える
web/static/js/app.js
は元々は
import {Socket} from "phoenix"
// let socket = new Socket("/ws")
// socket.connect()
// let chan = socket.chan("topic:subtopic", {})
// chan.join().receive("ok", chan => {
// console.log("Success!")
// })
let App = {
}
export default App
のようなスケルトンですが、これを
import {Socket} from "phoenix"
// let socket = new Socket("/ws")
// socket.connect()
// let chan = socket.chan("topic:subtopic", {})
// chan.join().receive("ok", chan => {
// console.log("Success!")
// })
$(function() {
React.render(
<h1 className="jumbotron">Hello from React!!!</h1>,
document.getElementById('hello_world')
);
});
let App = {
}
export default App
のように書き換えます。
サーバーを再起動するか、サーバーを立ち上げたままでも編集によってファイルの内容が変わるとそれを検知して自動的にリビルドが開始されますが、初回だけものすごく時間がかかります(非力なマシンだと1分以上かかる)。最初これに気づかずに何度もリロードしたりサーバーを止めたりしてジタバタしてしまいました。
最終的に
↑この画面が出たら成功です。
あとはReact関連のところをいろいろ書き換えて試してみることができます。