Clojure Web Development勉強 - Clojurescript(その1)cljs.jarでコンパイル
一旦サーバサイドを離れて、フロントエンドの開発を進めてみる。
フロントエンドについては以前から少し試していて、拙いながらも渋谷のLisp.Meetupでもライブコーディングしながらプレゼンしたことがある。その時はClojurescriptからFigwheel、Reagent、d3.jsなどと結構いろんな部分に言及できた(その分話が散漫になったきらいはあるが・・・)。
初心に戻ってもう一度簡単なところから調べていきたい。
というわけで、生のclojurescriptをコンパイルするところから。
公式サイトの上記のドキュメントをタネに、最低限のClojurescriptを書いてコンパイルして表示してみる。
そのコードというのはこれ:
(ns manual_clojurescript.core) (js/alert "Hello Clojurescript!")
名前空間の定義と、ブラウザのアラート機能で"Hello Clojurescript!"と表示させるだけ。js/alert
はClojurescriptからJavaScriptの機能を呼び出している。とりあえずこれをcore.cljsとしておく。Clojurescriptなので.cljsである。(cljcの話は違う記事で言及する)
さて、コードを書いたはいいが、これをどうすればいいのか。以下の三つのステップが必要になる。
- ClojurescriptをJavaScriptにコンパイル
- JavaScriptをロードするHTMLドキュメントを作成
- HTMLドキュメントをブラウザで表示
そのために幾つかサポートのためのファイルとディレクトリ構成を設定する。最終的に以下のような構成になる。
. ├── build.clj ├── cljs.jar ├── index.html └── src └── manual_clojurescript └── core.cljs
core.cljsがsrc/manual_clojurescript/のディレクトリの下にあるに注意。それ以外のファイルは全てディレクトリのトップレベルにある。
ClojurescriptをJavaScriptにコンパイル
さて、まずステップ1のために必要なcljs.jarとbuild.cljについて。
cljs.jarはQuick Startに載っているリンクから落とせる、Javaで書かれているClojurescript->Javascriptコンパイラである。
そのコンパイラに出す指示を入れたファイルがbuild.cljで、内容は以下のようになっている。
(require 'cljs.build.api) (cljs.build.api/build "src" {:output-to "out/main.js"})
srcディレクトリに含まれているcljsファイルをJSにコンパイルして、まだ未作成のoutディレクトリのmain.jsファイルに出力してくれ、という内容。
src/manual_clojurescript/core.cljs、build.cljそしてcljs.jarの三つが揃えばステップ1のコンパイルができる。bashから
で、outというディレクトリにmain.jsやその他もろもろが作成されるはずだ。構成としてはこんな感じ:
. ├── build.clj ├── cljs.jar ├── index.html ├── out │ ├── cljs │ │ ├── core.cljs │ │ ├── core.js │ │ └── core.js.map │ ├── goog │ │ ├── array │ │ │ └── array.js │ │ ├── asserts │ │ │ └── asserts.js │ │ ├── base.js │ │ ├── debug │ │ │ └── error.js │ │ ├── deps.js │ │ ├── dom │ │ │ └── nodetype.js │ │ ├── math │ │ │ ├── integer.js │ │ │ └── long.js │ │ ├── object │ │ │ └── object.js │ │ ├── reflect │ │ │ └── reflect.js │ │ └── string │ │ ├── string.js │ │ └── stringbuffer.js │ ├── main.js │ └── manual_clojurescript │ ├── core.cljs │ ├── core.cljs.cache.json │ ├── core.js │ └── core.js.map └── src └── manual_clojurescript └── core.cljs
outに見えるファイルの概要は以下のとおり:
- manual_clojurescriptディレクトリ:srcに含まれていた自前のclojurescriptコードのコンパイル先
- cljsディレクトリ:clojurescript自体の言語機能やライブラリが含まれている
- googディレクトリ:Clojurescriptが乗っかっているGoogleのオープンソースJavaScriptライブラリであるGoogle Clojure Libraryの出力先
- main.js:上記のディレクトリに含まれているJSをつなぎ合わせるコード
JavaScriptをロードするHTMLドキュメントを作成
さて、次はこのコンパイルされたJavaScriptのロード先であるHTMLドキュメント、index.htmlを作成する。今回は最低限ということで以下のようなファイルになる:
<html> <body> <script type="text/javascript" src="./out/goog/base.js"></script> <script type="text/javascript" src="./out/main.js"></script> <script type="text/javascript">goog.require("manual_clojurescript.core");</script> </body> </html>
まずGoogle Closure Libraryの便利機能を裏で色々使うので、それをgoog/base.jsを通じてロードしておく。
次に自分の書いたコードも呼び出せるようmain.jsをロード。
最後に、Google Closure Libraryのgoog.requireを使って自分の書いたClojurescriptのコンパイル先であるmanual_clojure.coreを実行。これで、core.cljsに記述したロジックに従って処理が行われる。
HTMLドキュメントをブラウザで表示
それでは実際に走らせてみる。
一番手軽なのはbashから
open ./index.html
でローカルファイルとして開いてしまうこと。これでちゃんとアラートポップアップに"Hello Clojurescript!"と表示されるはず。
もうちょっとちゃんとローカルサーバ立ててみたい場合は:
python -m http.server
あるいは
python -m SimpleHTTPServer
(前者はPython 3.x、後者はPython 2.xの場合)
のようにサーバ立ててブラウザでlocalhost:8000などと見てもオッケー。
とりあえず最低限のClojurescriptを書いてコンパイルしてロードするHTML用意して開くところまでは来れた。次はlein-cljsbuildを使ったコンパイルプロセスの簡略化と自動化。