Clojure Web Development勉強 - ClojureScript(その4)figwheelの最小限設定
Figwheelは素晴らしい。FigwheelはClojureScriptを使うことで得る大きな喜びの一つだ。
と過剰に思われる売り込みで始める。しかし、個人的には全く誇張している意識はない。
Figwheelはwebsocketを使って、ソースファイルの変更を自動的にブラウザに反映させる開発ツールである。
前回lein cljsbuild autoでClojureScriptからJavaScriptへのコンパイルを自動化し、ソースファイルを変更して保存すれば自動的にJavaScriptが生成され、そのあとブラウザをリロードすることで変更を反映させることができる、というワークフローを紹介した。
Figwheelはそれをもう一歩進めた形になる。ClojureScriptのソースファイルを変更・保存した時点でブラウザリロードする必要なく自動的にブラウザに新しいJavaScriptがロードされる。
文章で説明しても凄さがいまいち伝わらない感があるが、動画で見た時は相当な衝撃を受けたのを覚えている。見たのはfigwheelの開発者Bruce Haumanによる紹介動画:
そして実際に使うとさらに感動する。「cljsbuildから一歩進んだ」というのは正しいが、その一歩がいかに重要かを充分伝えきれていないと思う。
まず、エディタから離れることなくブラウザで変更が確認できる。私の場合はvimを使っているのだが、:wと叩いた時点でブラウザに反映される。書いては:w、書いては:wでホームポジションから手を離すことなしに開発サイクルが回る。
そしてページリロードをしないことで状態が維持される。リロードした場合ページが初期状態に戻されてしまい、例えばそこから状態を色々変更していた場合、前回と同じ変更を加えていって手動でリロード前の状態に戻す必要が生じる。Figwheelを使うとその必要がなく、コード変更前のページの状態のまま挙動などが変わるのを確認できる。
今回のコード:
ポイントとなるのは3点。
- pluginsにlein-figwheelを追加する
- cljsbuildの:optimizationsがないビルドに:figwheel trueを追加する
- output-to/output-dirをresources/publicディレクトリのどこかにする
最初の二つはleiningenとcljsbuildにちゃんとfigwheelと連動するよう伝えるオプション。
三つ目のポイントは、figwheelが自動的に立ち上げてくれるローカルサーバがデフォルトでresources/pubicをルートディレクトリにしているので、サーバからアクセスするファイルはhtmlであれjavascriptであれすべてresources/publicの下位ディレクトリ(あるいはresources/public内)になくてはいけない。
これでlein figwheel
とコマンドを走らせると
Figwheel: Cutting some fruit, just a sec ... Figwheel: Validating the configuration found in project.clj Figwheel: Configuration Valid :) Figwheel: Starting server at http://0.0.0.0:3449 Figwheel: Watching build - dev Figwheel: Cleaning build - dev Compiling "resources/public/js/main.js" from ["src"]... Successfully compiled "resources/public/js/main.js" in 11.823 seconds. Launching ClojureScript REPL for build: dev Figwheel Controls: (stop-autobuild) ;; stops Figwheel autobuilder (start-autobuild [id ...]) ;; starts autobuilder focused on optional ids (switch-to-build id ...) ;; switches autobuilder to different build (reset-autobuild) ;; stops, cleans, and starts autobuilder (reload-config) ;; reloads build config and resets autobuild (build-once [id ...]) ;; builds source one time (clean-builds [id ..]) ;; deletes compiled cljs target files (print-config [id ...]) ;; prints out build configurations (fig-status) ;; displays current state of system Switch REPL build focus: :cljs/quit ;; allows you to switch REPL to another build Docs: (doc function-name-here) Exit: Control+C or :cljs/quit Results: Stored in vars *1, *2, *3, *e holds last exception object Prompt will show when Figwheel connects to your application
こんな感じのメッセージが出力される。
あとはブラウザからlocalhost:3449
にアクセスするとindex.htmlが開き、コンパイルされたJavaScriptが走る。
ChromeのJavaScriptコンソールなどを立ち上げると
Figwheel: trying to open cljs reload socket utils.cljs?rel=1478607372893:49 Figwheel: socket connection established utils.cljs?rel=1478607372893:49
とソケットで通信していることがわかる。
これでcore.cljsをいじって保存してみる。例えば
(ns min-figwheel.core) (js/alert "Hello ClojureScript!")
を
(ns min-figwheel.core) (js/alert "Hello Figwheel!")
に変更してセーブする。それだけで自動的に新しいアラートメッセージがブラウザ上で表示される。
あるいは
(ns min-figwheel.core) (js/console.log "Hello Figwheel!")
と変更してコンソールを確認すると
Figwheel: notified of file changes utils.cljs?rel=1478607372893:49 Hello ClojureScript! core.cljs?rel=1478641111736:2 Figwheel: loaded these files utils.cljs?rel=1478607372893:49 ("../min_figwheel/core.js") utils.cljs?rel=1478607372893:51
こんな風に表示される。ちゃんとソースの変更が反映されてコンソール出力できているのがわかる。core.cljsのどこに対応しているのかまで表示していて、リンクをクリックするとソースが確認できるのもなかなか面白い。
さて、今まで恐ろしく簡単なClojureScript機能しか使ってきていないので、Figwheelのありがたみがまだ明確に出てきていない。Figwheelの真価が発揮されるのはClojureScriptで複雑な処理を書き出してからである。特に、FigwheelとDOM操作系のライブラリを合わせることでページをグリグリと非常にインタラクティブに作成できるようになる。
次はClojureScript上でどうやってDOM操作をしていくかという観点からReactについて書きたい。