Leiningen をインストールする
(JDKなどJavaの開発環境がインストールされている前提)
Clojure でのプロジェクト管理ツールのデファクトスタンダードである Leiningen をインストールする。
brew install leiningen
などする。
基本的な使い方は以下が参考になりました。
emacs の設定
Clojure の開発環境は Emacs が最強らしい。
なので、emacs に cider をインストールする。
Emacs の環境構築に関して以下を読む。
~/.lein/profiles.clj
に以下の記述をする。(最新版のciderでは不要のようです。)
{:user {:plugins [[cider/cider-nrepl "0.8.1"]]}}
- 基本的な使い方は以下。
cider-jack-in で repl に接続する。
C-x C-e (cider-eval-last-expression) で実行
C-c M-n で repl の名前空間を設定
C-c C-k でカレントセッションをコンパイル
C-c M-n カレントバッファのnamespaceを切り替える
C-c C-k カレントバッファをコンパイル
C-c C-d C-d カーソルポイントのドキュメント表示
M-. and M-, Navigate to source code for symbol under point and return to your original buffer.
C-c C-d C-a Apropros search; find arbitrary text across function names and documentation.
*cider-errpr* は Emacs キーバインドで q で消せる
cider-find-var で def, defn の定義元ジャンプ
C-c C-q で REPL と 関連バッファを消す
IntelliJ IDEA
普段は IntelliJ を使うことが多いので CurisiveIDE も考慮に入れる。
emacs の学習コストが高い場合は Cursive でがんばるのも良さそう。
無料版は6ヶ月毎にライセンスキーの更新が必要になる。
仕事で使う場合は有料ライセンスの購入が必要、買い切り型で1年間の無料アップデートできる。
ClojureScript コンパイラ
基本はClojure公式の cljs.jar を叩いたり Leiningen を使う。
共にClojure製なので、実行に JVM が必要。
最近、NodeJS上で動作する ClojureScriptコンパイラである lumo というのが出てきた。
これは ClojureScript のソースコードを自分自身で js に変換し、それをNodeJSに載せたものらしい。
lumo によって ClojureScriptが js でセルフホストされたので、JVMの環境を用意しなくても Node があれば ClojureScript を利用することができるようになった。
ただし、lumo が利用している js版の GoogleClosureCompiler の advancedコンパイルの最適化がJava製のより弱いらしいので、その点を気にするなら今のところは JVM版を使用したほうが良いとのこと。
GoogleClosure
ClojureScript は Google Closure Library (GCL)にガッツリ依存している。
細かなエラーは GCL について知っていると解決することが多いらしい。
詳しくは公式サイトを参照のこと。
https://clojurescript.org/about/closure
ClosureLibrary
ClojureScript は Google の ClosureLibrary を組み込みで提供している。
ClojureScript を書いていて何か機能が足りなかったりした場合は、外部ライブラリを探す前に、先に GCL のドキュメントを参照して利用できるものが無いか探してみる。
GCL の機能を把握していると色々と捗るだろう。
ClosureCompiler
ClojureScript はコンパイル結果のjsを ClosureCompiler を通して最適化する。
開発時などは :none
や :simple
を指定してあまり最適化しないかもしれないが、プロダクションビルド時には :advanced
で積極的な最適化を行うことが推奨されている。
積極的な最適化では、関数のインライン化や変数名のリネーム、デッドコードの削除などを行いビルド後の js のサイズがかなり小さくなるらしい。
外部ライブラリの利用
ClojureScript は 当然通常の JavaScript のライブラリを使用できる。
素のJavaScriptのメソッドは以下のように js/
ネームスペースから呼び出せる。
(js/console.log "hello, world")
(.html (js/$ "#cljs-test") "clojure")
ただし、このまま ClosureCompiler の積極的な最適化を行うと以下のように実行エラーが発生する。
Uncaught TypeError: $(...).Ge is not a function
at Ni (main.js:320)
at cljs_entry_point (main.js:320)
at (index):8
Ni @ main.js:320
cljs_entry_point @ main.js:320
(anonymous) @ (index):8
これは、 $().html
な呼び出し部分が最適化によって $().Ge
と変換されてしまい、未定義メソッドの呼び出しエラーとなってしまうから。
これを避けるためにはいくつかの方法がある。
- extern ファイルを用意して最適化時にリネームされないようにする
- cljsjs リポジトリで用意されている extern ファイルを依存関係に加える
- http://cljsjs.github.io/
- よく使われるJavaScriptライブラリの ClojureCompiler用の extern ファイルが用意されている
- TypeScript でいう DefinitelyTyped のようなもの?
このあたりの対応に関しては、以下の記事がとても参考になりました。
Advanced Compilation との戦い
React関連ライブラリ
-
reagent
- シンプルなReactラッパーらしい
-
re-frame
- reagent の上に作られたフレームワーク
-
Om
- ご存知 CircleCI で採用されている
- 独自用語が多く、概念がやや難しいとのこと
- reagent よりは学習コスト高めらしい
-
rum
- 最近の流行りらしい
- reagent より rum のほうがSSRが簡単らしく、SSRやるならこちらが良いのでは、とのこと。
figwheel
figwheel はモダンな ClojureScript の開発に必須のライブラリ。
cljsの自動コンパイルとホットコードリローディングの機能を提供する。
lein new figwheel figwheel-sample
などして使い始める。
参考: https://www.youtube.com/watch?v=j-kj2qwJa_E
手を動かす
-
https://clojurescript.org/guides/quick-start
- まず読む公式サイトの入門ページ
参考になりそうな資料など
その他
- Leiningen重いんだけど
- -> 落としたら負け
- OracleJDK と OpenJDK
- Clojure界隈ではOpenJDKがデファクトらしい
- java の知識
- 環境構築にJVMは必要だけど、lumoとか作れるくらいだし、cljsには必要なさそう
- nREPL
- https://github.com/clojure/tools.nrepl
- socket 経由で Clojure のREPLに接続するツール
- 色々なプラグインや開発環境から利用される
- Clojureの快適な開発環境は nREPL のおかげらしい
謝辞
この記事に書かれている内容の大部分は、勉強会で同席した @iku000888 さんに教えていただきました。
ClojureScript に関して何もわからない状態から、大まかな概要を把握するところまでショートカットすることができました。
ありがとうございました。