ClojureScript

クイックスタート

macOS または Linux を使用している場合、このチュートリアルの主要部分に必要な依存関係は、WebブラウザとClojureのインストールだけです。Windowsの場合は、Java 8スタンドアロンのClojureScript JARが必要です。Webブラウザが必要であるため、ヘッドレス環境は除外されます。そのため、チュートリアルのNode.jsの部分をざっと読むことをお勧めします。

Hello, ClojureScript

このチュートリアルでは、簡単なClojureScriptプロジェクトのコンパイルと実行、および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        # (macOS/Linux only) A file for listing our dependencies

macOSまたはLinuxを使用している場合、`deps.edn`ファイルには次の内容を含める必要があります。

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

お好みのテキストエディタで`src/hello_world/core.cljs`を編集し、次のようになります。

(ns hello-world.core)

(println "Hello world!")

簡単なプログラムができたので、ClojureScriptをビルドして実行してみましょう。`hello-world`プロジェクトディレクトリにいることを確認し、次のコマンドを実行します。

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

Windowsの場合

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

デフォルトのWebブラウザが開き、次のページが表示されます。

Browser REPL Serving Default index.html

Linuxを実行していてREPLが開始しない場合は、ブラウザの自動起動を無効にして、`https://:9000`を手動で開いてみてください。

clj -M --main cljs.main --repl-opts "{:launch-browser false}" --compile hello-world.core --repl

数秒後、ターミナルに`Hello world!`と表示され、REPLプロンプトが表示されます。次の例のようにいくつかの式を試してみてください。

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

ここで使用したフラグを詳しく見てみましょう。`--main`は、この場合は`cljs.main`という *Clojure* 関数を呼び出します。`cljs.main`関数は、一般的なタスクを指定するためのさまざまなコマンドライン引数をサポートしています。`--compile`を使用して、`hello-world.core`名前空間をコンパイルすることを指定しています。その後、`--repl`を使用して、コンパイルが完了したらすぐにREPLを起動することを指定しています。

`src/hello_world/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])`を実行してみてください。ClojureScriptのソース位置ではなく、JavaScriptのソース位置を指す、ソースマップされたスタックトレースが表示されます。これにより、デバッグがはるかに容易になります。

`--help`を使用して、ClojureScriptコンパイラによって提供されるオプションを簡単に調べることができます。これまでに使用したすべてのオプションの省略形フラグがあることがわかります。

clj -M -m cljs.main --help

Windowsの場合

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

`--compile`、`--main`、`--repl`などのいわゆるメインオプションは、常に最後に来る必要があることに注意してください。

本番ビルド

コンパイルされたJavaScriptを含む`out`ディレクトリに気づかれたかもしれません。そこに約6.5メガバイト分のJavaScriptがあります。これは扱いにくいように思えるかもしれませんが、幸いなことに、ClojureScriptコンパイラはGoogle Closure Compiler用に最適化された出力を生成します。Google Closure Compilerは多くの最適化を実行し、ブラウザベースのクライアントにとって最も重要なのは、ミニファイとデッドコードの削除です。

先に作成したREPLの変更を`src/hello_world/core.cljs`から削除しましょう。

(ns hello-world.core)

(println "Hello world!")

`--optimizations`フラグの適切な値を設定することで、リリースビルドを作成できます。デフォルトの最適化レベルは`none`ですが、今回はClojureScriptとGoogle Closure Compilerの両方によって提供されるすべての最適化を使用します。これは`advanced`を指定することで行うことができます。`--optimizations`の他の有効なオプションは`whitespace`と`simple`ですが、これらはあまり使用されません。

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

Windowsの場合

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

このプロセスにはかなり時間がかかるため、開発にはこのコンパイルモードを使用しません。

`out/main.js`を確認してください。ファイルサイズは約90KBです。このファイルをzip圧縮すると、約20KBになります。これはjQueryの依存関係よりもはるかに小さいですが、ClojureScriptを使用すると、ClojureScript標準ライブラリ全体(10KLOC)とGoogle Closure Library(300KLOC)への暗黙的な依存関係があります。デッドコードの削除のおかげです。

`--serve`フラグを使用して、組み込みのシンプルなWebサーバーを実行して、このファイルがまだ機能することをテストできます。

clj -M -m cljs.main --serve

Windowsの場合

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

このコマンドはREPLを開始しないため、ブラウザウィンドウは自動的に開きません。お好みのブラウザを使用して`https://:9000`にアクセスしてください。JavaScriptコンソールを確認すると、`Hello world!`と表示されているはずです。組み込みのWebサーバーはJavaScriptコンテンツをgzip圧縮します。ブラウザのJavaScriptコンソールのネットワークタブを確認すると、JavaScriptペイロードの合計が約20KBになっていることを確認できます。

Node.js での ClojureScript の実行

まず、Node.jsがインストールされていることを確認してください。Node.jsのインストール方法については、Node.js wikiを参照してください。現時点では、Node.jsの現在の安定版(>= `0.12.X`)のみがサポートされています。

先に進む前に、ソースマップを有効にします。

npm install source-map-support

Nodeプロジェクトをビルドしましょう。`--target`を使用して、特定のJavaScriptターゲットのコードを生成することを指定できます。`--target`フラグが指定されていない場合、ClojureScriptはブラウザ用のコードを生成します。ここでは`--output-to`を使用して`--output-to`ファイルを指定しています。

clj -M -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

**注記:** Node.jsでは、高度な最適化を使用する理由はほとんどありません。高度な最適化はパフォーマンス関連の最適化を適用しますが、これらは現在、V8、SpiderMonkey、JavaScriptCoreなどの最新のJavaScript仮想マシンにある最適化によって大部分が回避されています。Node.jsの場合、`simple`または`none`の最適化で十分です。

Node.js REPL

Node.js REPLの実行は、ブラウザREPLの実行に似ています。異なるJavaScript評価環境を使用するREPLを指定するには、`--repl-env`を指定します。この値はデフォルトでブラウザREPLですが、ここでは`node`を指定します。

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

Windowsの場合

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

ブラウザについて前述したREPLのやり取りはすべて機能するはずです。

依存関係

ClojureScriptは、ClojureScriptとJavaScriptの依存関係を含めるためのさまざまなオプションをサポートしています(詳細については依存関係を参照してください)。

Reactは、ClojureScriptプロジェクトで人気のある依存関係です。CLJSJSバンドル版を提供しています。これを含める方法を見てみましょう。

`deps.edn`ファイルを修正します。

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

Reactが正しくrequireされるように、簡単なプログラムを次のように編集しましょう。

(ns hello-world.core
  (:require react-dom))

(.render js/ReactDOM
  (.createElement js/React "h2" nil "Hello, React!")
  (.getElementById js/document "app"))

ビルドして実行しましょう。

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

ブラウザが起動すると、すぐにデフォルトページが表示され、すぐに`Hello React!`を含む`h2`タグに置き換えられます。

原著者:David Nolen