LoginSignup
19
7

More than 3 years have passed since last update.

shadow-cljs

Last updated at Posted at 2017-08-17

shadow-cljsというツールが話題になっていたので触ってまとめてみた。
npm界隈を知らないので認識が違うこともあるかもしれない。

バージョンは0.18.7を使用している。

目的

READMEによると以下の目的があって作られた物らしい

  • ClojureScriptのデフォルトのビルドapiを親切な物で置換する
  • ClojureScriptのビルドと既存のJavaScriptとのビルドツール間の連携を行いやすくする

特徴

  • npm/yarnがあればインストールできる
    • Javaがインストールされていない場合はnode-jreにフォールバックする
      • node-jreはnpm/yarnでインストールすることができる
  • 1つビルドの設定から、開発用ビルド/リリースビルドのような異なるタスクが実行できる。
    • ClojureScriptのAPIの場合、タスク毎にそれぞれ異なるビルドの設定が必要で冗長になりがち
  • 単一のcliツールとして利用することができる
  • Clojureのライブラリとして使うこともできる

機能

  • ビルドができる
  • npmモジュールとの密な連携
    • npmモジュールを特別な設定無くnamespaceとして使える
    • externも大体ケアされる
  • figwheelのようにファイルの変更を検知→ホットローディングが可能
    • 演出は無く、コンソール出力のみ -> shadow-cljsロゴが表示されるようになった
  • cljs-replが起動できる
  • 依存関係を解決できる(内部でleiningenが使っている物を使用している)

インストール

npm/yarnでインストールすることができる。

# yarn
yarn global add shadow-cljs

# npm
npm install -g shadow-cljs

ざっくりとした利用方法

とりあえずcliツールとして使う場合のみを考慮する

shadow-cljs.ednをプロジェクトのルートに用意する

  • ビルドの設定ファイル
  • shadow-cljs initでスケルトンを生成することができる
  • 以下のような感じ
{:source-paths
 ["src"] ;; ソースコードがあるパスを書く

 :dependencies 
 ;; 1. Clojure,ClojureScriptはshadow-cljs本体に含まれるため指定しない
 ;; 2. Leiningenと同じ形式で指定する
 [[reagent "0.7.0"]]

 :builds
 {:my-app ;; build-id。複数可能
  {:target :browser ;; nodeやカスタムターゲットを設定できる
   :output-dir "shadow-out/js" ;; ビルドを出力をするディレクトリ
   :asset-path "/js" ;; 開発時の依存モジュールをGETしに行く際のルートディレクトリ
   ;; メインのネームスペースを指定する
   :modules {:main {:entries [my-app.app]}}
   ;; コードのホットリロード時に実行される関数を指定する
   :devtools {:before-load my-app.app/before-load
              :after-load my-app.app/after-load }
   ;;ClojureScriptコンパイラがサポートしているパラメータを渡せる
   :closure-defines {myapp.app.foo "foobar"}}}}

ビルドする

  • shadow-cljs <compile|watch|cljs-repl|release> <build-id> でビルドする
  • compile - 開発時の設定で一度だけビルドする
  • watch - ソースの変更を検知してビルドを行う。コードのホットリロードはこれで行う
  • cljs-repl - ビルドにreplクライアントを含め、それに接続する
  • release - ClojureScriptコンパイラで言うところの :optimizations :advanced でビルドする。
    • 開発用(ホッロリロード/repl)コードがビルドに含まれない

詳細

この辺を読んだら仕事のプロジェクトはビルドできた

感想

  • ClojureScriptの開発時に欲しい機能が1つにまとまっている
  • leiningen/bootに依存していない
  • ビルドの設定が開発時とリリース時で共通にできるのでスッキリする

以上の点からClojureScriptのアプリケーションを開発するだけであれば非常に魅力的なツールだという印象を持った。
Clojureのライブラリとしても利用できるようなので、好みが合うのであればfigwheelやcljsbuildをこれで置換しても良いと思う。

余談

1. warningが親切だった

たまたまwarningが含まれるプロジェクトをビルドしてみたのだが、
出力が親切だったのが新鮮だった。

[:my-app] Build completed. (161 files, 45 compiled, 1 warnings, 23.37s)

------ WARNING #1 --------------------------------------------------------------
 File: clojure/reflect.cljs
--------------------------------------------------------------------------------
  29 |   [sym cb]
  30 |   (query-reflection (str "var=" (js/encodeURIComponent (str sym)))
  31 |                     #(cb (evaluate-javascript %))))
  32 | 
  33 | (defn macroexpand
-------^------------------------------------------------------------------------
 macroexpand already refers to: cljs.core/macroexpand being replaced by: clojure.reflect/macroexpand
--------------------------------------------------------------------------------
  34 |   "Queries the reflection api with a quoted macro form, then calls the
  35 |   callback function with the macroexpanded form, as a string."
  36 |   [form]
  37 |   (query-reflection (str "macroform=" (js/encodeURIComponent (str form))) println))
  38 | 
--------------------------------------------------------------------------------

2. Readmeの内容が間違っているっぽかったのでプルリク送った

19
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
7