Clojure
ClojureScript

ClojureScript クイックスタート (1.10.238 Release)

ClojureScript の本家サイトにある Quick Start の記事をざっくりとまとめる。

1.10.238 Release 以前の古い記事はこちら
(だいぶ、短くなった)

事前準備

Hello, ClojureScript

このチュートリアルでは、単純な CloureScript のプロジェクトのコンパイルと実行、および REPL を実行し、インタラクティブにコードを開発、テストする方法について説明する。

まず、以下の構成のプロジェクトを作成する。ディレクトリ構造とアンダースコア(hello_world)は変更しないこと。

hello-world        # Our project folder
├─ src             # The CLJS source code for our project
│  └─ hello_world  # Our hello_world namespace folder
│     └─ core.cljs # Our main file
├─ cljs.jar        # (Windows only) The standalone Jar you downloaded earlier
└─ deps.edn        # (Mac/Linux only) A file for listing our dependencies

Mac or Linux ユーザは以下を記述した deps.edn を用意する。

deps.edn
{:deps {org.clojure/clojurescript {:mvn/version "1.10.238"}}}

お好きなエディタで src/hello_world/core.cljs を以下のように編集する。

core.cljs
(ns hello-world.core)

(println "Hello world!")

これで簡単なプログラムの完成。以下のコマンドでビルド&実行してみましょう。

Mac or Linux

clj --main cljs.main --compile hello-world.core --repl

Windows

java -cp "cljs.jar;src" cljs.main --compile hello-world.core --repl

デフォルトのブラウザで以下のようなページが表示される。

Browser

数秒後、ターミナルに "Hello world"が出力され、REPL のプロンプトが表示される。

REPL で以下の式が評価できることを確認。

(inc 1)
(map inc [1 2 3])
(.getElementById js/document "app")

実行したコマンドを詳しく確認する。

--main は Clojure 関数を呼び出すためのフラグ。ここでは cljs.main 関数を呼び出している。cljs.main 関数はいくつかのタスクを行うコマンドをサポートしており、ここでは --compilehello-world.core 名前空間のコンパイルを実行している。後に続く --repl フラグでコンパイル完了後、REPL を起動することを指定している。

src/hello_world/core.cljs を以下のように書き直してみましょう。

core.cljs
(ns hello-world.core)

(println "Hello world!")

;; ADDED
(defn average [a b]
  (/ (+ a b) 2.0))

REPL プロンプトで以下を評価し、名前空間のリコンパイル&リロードを行う。

(require '[hello-world.core :as hello] :reload)
(hello/average 20 13)

結果として 16.5 が出力されるはず。

以下の式を評価し、わざとエラーを発生させてみましょう。

(ffirst [1])

JavaScript ではなく、ClojureScript のソース位置を示すスタックトレースが出力され、デバッグを容易にする。

cljs.main で指定できるオプションは --help オプションで確認できる。

clj --main cljs.main --help

今まで使ったオプションの省略フラグ(--mainの代わりに-m)が使えることが確認できる。

--compile, --main, --replといったメインオプションは常に最後に記述する必要があることに注意する。

Production Builds

コンパイルされた全ての JavaScript を含む out ディレクトリは約6.1MB ある。ClojureScript のコンパイラは Google Clojure Compiler に最適化された出力を生成する。Google Clojure Compiler では 最も重要な縮小化とデッドコードの削除を含む、多くの最適化が実行される。

src/hello_world/core.cljs を元に戻す。

core.cljs
(ns hello-world.core)

(println "Hello world!")

--optimizations フラグに適切な値を設定することにより、リリース用のビルドを作成することができる。デフォルトの最適化レベルは none に設定されているがここでは、ClojureScript と Google Closure Compiler で提供されている全ての最適化を利用したいため、advanced を指定する。その他に whitespace, simple--optimizations として指定することができる。

Mac or Linux

clj -m cljs.main --optimizations advanced -c hello-world.core

Windows

java -cp "cljs.jar;src" cljs.main --optimizations advanced -c hello-world.core

advanced コンパイルには時間がかかるため、開発中には使用しない。

out/main.js を調べるとファイルサイズは約90Kだとわかる。zip に圧縮すると 20Kほどになり、jQuery の依存関係よりもかなり小さいことがわかる。ただし、ClojureScript には ClojureScript standard library (10KLOC) と Google Closure Library (300KLOC) への暗黙的な依存がある。

--serve フラグにより、ビルドインされているシンプルなウェブサーバを起動し、main.js 動作を確認することができる。

Mac or Linux

clj -m cljs.main --serve

Windows

java -cp "cljs.jar;src" cljs.main --serve

このコマンドでは REPL が起動しないので、直接ブラウザで http://localhost:9000 にアクセスして動作を確認する。
Hello world!が出力されていることを、JavaScript のコンソールで確認することができる。

Running ClojureScript on Node.js

まず、Node.js がインストールされていることを確認。インストールされていない場合は、Node.js wikiを参考にインストールする。

先に進む前に、source mapping を有効にする。

npm install source-map-support

--target オプションで特定の JavaScript をターゲットにしたコードを生成することができる。--targetが指定されていない
場合、ブラウザ向けのコードが生成される。ここでは、出力されるファイル名を指定するため、--output-to オプションも利用している。

Mac or Linux

clj -m cljs.main --target node --output-to main.js -c hello-world.core

Windows

java -cp "cljs.jar;src" cljs.main --target node --output-to main.js -c hello-world.core

以下で、実行することができる。

node main.js

Note
最新の JavaScript エンジン (V8, SpiderMonkey and JavaScriptCore) の最適化が優れているため、Node.js では :advanced で最適化を行う理由はほとんどない。 :simple or :none の最適化で十分。

Node.js REPL

--repl-env で JavaScript の評価環境を指定することができる。デフォルトでは、ブラウザ REPL が設定されている。

Mac or Linux

clj -m cljs.main --repl-env node

Windows

java -cp "cljs.jar;src" cljs.main --repl-env node

今までブラウザ REPL で試した式の評価は、Node.js でも正しく機能する。

Dependencies

ClojureScript は ClojureScript と JavaScript の dependencies を扱う様々な方法がある。
詳しくは Dependenciesを参照。

React は ClojureScript のプロジェクトで人気の dependency で、cljsjs により bundled versionが提供されている。この使用法を確認する。

deps.edn ファイルを修正する。

deps.edn
{:deps {org.clojure/clojurescript {:mvn/version "1.10.238"}
        cljsjs/react-dom {:mvn/version "16.2.0-3"}}}

React が使われるように src/hello_world/core.cljs を修正する。

以下で、ビルド&実行。

clj -m cljs.main -c hello-world.core -r

ブラウザで一瞬、デフォルトのページが表示されたあと、h2タグに Hello React! が記載されたページに置き換わることを確認することができる。