Open7

Clojure Scriptのキャッチアップ

kip2kip2

ClojureScriptをキャッチアップしていくぞい。

kip2kip2

プロジェクトの開始

プロジェクトの開始にあたって、慣れ親しんだleiningenではなく、Node.jsを使う方法もあるらしい。
https://qiita.com/lambda-knight/items/a69df35405b26f7a79cf

JavaScriptへのコンパイルツールなので、後々を考えると、Node.jsで使える方がいいのかな?

とりあえず、それぞれの方法で動かすだけ動かしてみる。

kip2kip2

Node.jsでのやり方

Node.jsを使って起動する方法をやってみる。

プロジェクトの作成

mkdir hello-cljs
cd hello-cljs
npm init -y

shadow-cljsをインストールする。

npm i shadow-cljs

shadow-cljsは、ClojureScriptのビルドのためのツールらしい。
他にも色々あるらしいが、JavaScriptと親和性が高いらしい。

https://github.com/thheller/shadow-cljs

shadow-cljsの設定

ルートディレクトリにshadow-cljs.ednという設定ファイルを作成。

;; shadow-cljs.edn
{:source-paths ["src"]
 :dependencies []
 :builds {:app {:target :browser
                :output-dir "public/js"
                :asset-path "/js"
                :modules {:main {:init-fn hello-cljs.core/init}}}}}

これで、public/js/main.jsにコンパイルされたJavaScriptファイルが配置されるようになる。
アプリのエントリーポイントはhello-cljs.core/initになっているらしい。

ClojureScriptコードを書く

src/hello_cljs/core.cljsファイルを作成する。

(ns hello-cljs.core)

(defn init []
  (js/console.log "Hello, ClojureScript!")
  (set! (.-innerHTML (.getElementById js/document "app")) "Hello, ClojureScript!"))

htmlファイルを用意

public/index.htmlファイルを作成する。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Hello ClojureScript</title>
</head>
<body>
  <div id="app">Loading...</div>
  <script src="/js/main.js"></script>
</body>
</html>

開発サーバーの起動

npx shadow-cljs watch app

本当はこれでhttp://localhost:9630にアクセスすればいいようなのだが...ダッシュボードにアクセスしてしまうので、次の方法でサーバーを立ち上げる。

npm i serve
npx serve public

成功。

しかし、serveくん、ポート番号毎回変わるんだっけ?
使うたびにポート番号変わってるのでちょっと驚いた。

kip2kip2

shadow-cljsについて

先程は動くコードが書けただけなので、ここからは色々調査して使ってみたい。

この記事を参照させていただきました。
https://qiita.com/lambda-knight/items/a69df35405b26f7a79cf

browser-repl

なんとブラウザでREPLができるらしい。

npx shadow-cljs browser-repl

以上でREPLが立ち上がるので、あとはコードを打ち込んでいけばいい。
なお、コマンドを入力した同じターミナルから実行する。

cljs.user=> (+ 1 1)
2
cljs.user=> (js/alert "Hello, World!")
nil

ハマった部分

基本的には記事のとおりにやればできたが、ちょっとハマった部分。

ファイル名に-は使えない。

-を使う場合は_に変更するということ。

kip2kip2

公式チュートリアル

さて、公式チュートリアルを触ってみる。

https://clojurescript.org/guides/quick-start

ディレクトリを作成

以下の構成で作成すること、と指示があったので作ってみる。

hello-world
├── cljs.jar
├── deps.edn
└── src
    └── hello_world
        └── core.cljs

dps.ednを編集

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

core.cljsを編集

(ns hello-world.core)

(println "Hello world!")

ビルド&実行

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

すると、ブラウザが自動で立ち上がり、以下のようなページが表示される。

REPLに入力

ビルドが終わると、REPLが立ち上がるので、以下のように入力してテストする。

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

ソースファイルの変更

(ns hello-world.core)

(println "Hello world!")

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

リロード

REPLで以下のコマンドを打ち込んで、リコンパイル&リロードする。

(require '[hello-world.core :as hello] :reload)

;; リロードが終わったら以下のコードを試す。
(hello/average 20 13)

プロダクションビルド

まず、先程の変更を削除する。

src/hello_world/core.cljs

(ns hello-world.core)

(println "Hello world!")

オプションを変えてビルドするだけでビルドできるらしい。

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

よくわかっていないが、src/outディレクトリに出力されているらしい。

Node.jsでClojureScriptを実行する

まずソースマッピングを有効化する。

npm i source-map-support

ビルドをする

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

作成できたファイルを、以下のコマンドで実行できる。

node ./out/main.js