Clojure Web Development勉強 - FigwheelでCSS Auto-Loading
Single Page Applicationで複雑かつ洗練されたGUIを実装するためには、一般的にHTMLで定義されている文書のコンテンツだけではなく、CSSで定義されているスタイルをどうコントロールするかも非常に重要なポイントになる。
JavaScriptで直接DOMにコンポーネントごとのスタイルを挿入することも可能なのだが、Reactの実例を見るとどちらかというとCSSは別途用意することの方が多いようである。コンポーネントのclassやid指定でCSSと紐付ける形になる。公式チュートリアルもこの方式を採っていた。
別にCSSファイルを用意するのはいいのだが、CSSの変更は普通HTMLをリロードしないと反映されない。せっかくFigwheelでClojureScriptの変更を自動的かつ即座に反映させているのに、コンポーネントの見た目をいじってもリロードしないと変化が見えないというのは片手落ちである。
幸いFigwheelには特定のディレクトリのCSSをモニタして、変更があればWeb Socketでオートロードしてくれる設定があるので使ってみる。
ディレクトリ構造
とりあえずこんな感じのディレクトリ構造
. ├── project.clj ├── resources │ └── public │ ├── css │ │ └── main.css │ └── index.html └── src └── min_css └── core.cljs
いつもの構成に加えてresources/public/css
にmain.cssを定義している。
HTML
もちろんHTML文書でこのmain.cssを指定している:
<html> <head> <link href="css/main.css" rel="stylesheet" type="text/css"> </head> <body> <div id="app"></div> <script src="js/out/goog/base.js"></script> <script src="js/main.js"></script> <script>goog.require('min_css.core')</script> </body> </html>
あとは今までどおりにreagent用のapp div作成とJavaScriptの呼び出し。
Reagentコンポーネント
core.cljsの中にあるReagentのmy-appコンポーネントで要素を三つ定義している:
(defn my-app [] [:div [:h1 "Hello Reagent"] [:p "Some random text in a regular p tag"] [:p.my-class "More random text in a my-class p tag"]])
h1とただのpとp.my-classである。Reactチュートリアルでも見たように、Reagentでは:tag.xでxクラス属性を、:tag#yでyというidをDOM要素に付与できる。
CSS
body全体とこの三つの要素のスタイルをCSSで定義する:
body { background: #ddd; } h1 { color: #f00; } p { font: 18px "Century Gothic", Futura, sans-serif; } .my-class { font-size: 12px; background: #ddf; }
見た目はひどいがまあサンプルだと思って・・・
Figwheel設定
あとはproject.cljでfigwheelにcssの在処を指定してオートロードするよう設定する:
(defproject min-css "0.0.1" :dependencies [[org.clojure/clojure "1.8.0"] [org.clojure/clojurescript "1.9.293"] [reagent "0.6.0"]] :plugins [[lein-cljsbuild "1.1.4"] [lein-figwheel "0.5.7"]] :figwheel {:css-dirs ["resources/public/css"]} ;ここ :cljsbuild {:builds {:dev {:source-paths ["src"] :figwheel true :compiler {:output-to "resources/public/js/main.js" :output-dir "resources/public/js/out/" :optimizations :none}}}})
一行figwheelへの指示を追加するだけ。
実行
あとはlein figwheelで実行してブラウザでlocalhost:3449を開くだけ。
core.cljsもmain.cssも変更して保存した瞬間にブラウザで変更が反映される。
スタイルを動的に変更できるようになるのはけっこう快感。CSSシークレットみたいな本をいろいろとイジリ倒してみたくなる。
次はCSSの指定もednで!という業の深い話を。