Arantium Maestum

プログラミング、囲碁、読書の話題

Clojure Web Development勉強 - Devcards(その1)最低限の設定

CSSをいじりたおす根気がなかった・・・

ということで話題を変えてFigwheelの作者でもあるBruce Haumanが作ったツールであるDevcardsについて書く。

Devcardsとは

DevcardsはClojureScript+Reactで作ったコンポーネントの動作を試すための環境を提供するツールである。

qiita.com

DevcardsをReagent+Figwheelと連動させる

今回はとりあえずDevcardsとFigwheelで、Reagentコンポーネントを表示・動的に変更できる環境を整える最低限の設定を紹介する。Devcardsはサンプルコードなどを見ると、SablonoというOmでよく使われるReact対応のHiccup構文ライブラリを使っていることが多いのだが、ちゃんとReagentにも対応しているので今までどおりReagentを使い続ける。

まずproject.clj:

(defproject min-devcards "0.0.1"
  :dependencies [[org.clojure/clojure "1.8.0"]
                 [org.clojure/clojurescript "1.9.293"]
                 [reagent "0.6.0"]
                 [devcards "0.2.2"]]

  :plugins [[lein-cljsbuild "1.1.4"]
            [lein-figwheel "0.5.7"]]

  :cljsbuild
  {:builds {:devcards {:source-paths ["src"]
                       :figwheel {:devcards true}
                       :compiler {:output-to "resources/public/js/main.js"
                                  :output-dir "resources/public/js/out/"}}}})

:dependenciesにdevcardsを追加、そしてcljsbuildの:figwheelオプションを今までtrueだったのを{:devcards true}に変えてある。

今回は簡素化のために省いたが、cljsbuild内で定義される複数buildsのうち、本番環境用のコンパイル設定であるprod、開発環境用のdevに加えて、devcardsという三つ目のbuilds設定を作成することが推奨されている。

index.htmlは今までどおり:

<!DOCTYPE html>
<html>
    <body>
        <script src="js/out/goog/base.js"></script>
        <script src="js/main.js"></script>
        <script>goog.require('min_devcards.core')</script>
    </body>
</html>

次にcore.cljs:

(ns min-devcards.core
  (:require
    [reagent.core :as r])
  (:require-macros
    [devcards.core :as d :refer [defcard]]))

(defn my-app []
  [:div
   [:h1 "Hello Reagent!"]
   [:h2 "Hello Devcards!"]])

(defn text-renderer [text]
  [:div
   [:h1 "Here is your text:"]
   [:p text]])

(defcard myapp
  (d/reagent my-app))

(defcard text1
  (d/reagent [text-renderer "Hello"]))

(defcard text2
  (d/reagent [text-renderer "Goodbye"]))

とりあえずreagent.coreに加えてdevcards.coreからdefcardマクロを使う。reagentコンポーネントとして定義したものを、devcards.core/reagentというマクロでReactコンポーネント化している。それをdefcardsマクロが受けとって表示する流れとなる。

reagent.coreは実は今回はいらないが、今後r/atomを使う時のためにrequireしておく。

これでlein figwheelを実行するとこんな感じの表示になる:

f:id:zehnpaard:20161123165527p:plain

ちなみに複数のbuilds設定がproject.cljで定義されている場合はlein figwheel <build名>、例えばlein figwheel devcardsと実行することになる。

figwheelが走っているのでコンポーネントのコードや引数をいじって即時反映させるなどして、非常にインタラクティブなUI開発が可能になる。devcards固有の良さは、いろいろな状態の同一コンポーネントを並べて表示させることで、コード変更がどの状況でどのような影響があるかを非常に見やすくしてくれるところ。

次回はdevcardsのreagent atomとの関連を見ていく。