ClojureScriptをKintone上で動かすまで

最近はひたすらKintoneをClojureScriptでカスタマイズする日々を続けており、
プロジェクトの定番みたいなのが固まりつつあるのでまとめてみた。

## インストールしておく物
- boot
   - 依存関係の解決やプロジェクトのタスクの実行する
   - 本質的にはleinでも良い

## プロジェクトの構造

最低限以下のようになる。
各ファイルの中身は後述する

```
├── boot.properties
├── build.boot
├── figwheel.edn
└── src
    └── my
        └── app.cljs
```

### 1.boot.properties
bootがデフォルトで利用しているバージョン以外のClojureを使用したい場合、以下の様なboot.propertiesファイルを
プロジェクトのルートに配置する必要がある。

後述のfigwheelは古いバージョンのClojureだと動かないので、強く推奨する。

```
BOOT_CLOJURE_NAME=org.clojure/clojure
BOOT_CLOJURE_VERSION=1.9.0-alpha17
BOOT_VERSION=2.7.2
```

### 2.build.bootのテンプレート
実際は必要に応じて改変するが、以下の内容を前提に話を進める

```clj
(set-env!
 :resource-paths #{"src"}
 :dependencies '[;; Kintone API Wrapper
                 [iku000888/cljs-ktn-trumpet "0.1.2"]
                 ;; ClojureScript project
                 [org.clojure/clojurescript "1.9.908"]
                 ;; Hot code reloading + cljs-repl
                 [figwheel-sidecar "0.5.13"]
                 ;; HTTPS server
                 [ring/ring "1.6.2"]
                 ;; cljs-repl
                 [com.cemerick/piggieback "0.2.2"]])

(require '[ring.adapter.jetty :as j])
(require '[ring.middleware.file :as rf])
(deftask start-jetty!
  "Create keystore by running the following in the project root
  'keytool -keystore keystore -alias jetty -genkey -keyalg RSA'"
  []
  (def jetty
    (j/run-jetty
     (rf/wrap-file nil ".")
     {:host "localhost"
      :http? false
      :ssl? true
      :ssl-port 4443
      :keystore "keystore"
      :key-password "foobar";;depends on value entered at keystore creation
      :join? false})))

(require '[com.stuartsierra.component :as component])
(require '[figwheel-sidecar.system :as sys])
(deftask start-figwheel []
  (def system
    (component/system-map
     :figwheel-system
     (sys/figwheel-system (sys/fetch-config))))
  (alter-var-root #'system component/start)))

(deftask cljs-repl!! []
  (sys/cljs-repl (:figwheel-system system)))

(deftask dev-setup []
  (start-jetty!)
  (start-figwheel)
  (cljs-repl!!))

(require '[cljs.build.api :as b])
(deftask release-build []
  (b/build "src"
           {:main 'my.app
            :output-to "out/app.js"
            :output-dir "out"
            :optimizations :advanced}))
```

### 3.figwheel.edn

figwheelを動かすための設定
`asset-path`にhttpsを指定するのが超重要

```clj
{:http-server-root "public" ;; default
 :server-port 3449          ;; default
 :builds [{:id "app",
           :source-paths ["src"],
           :figwheel true
           :compiler
           {:main mc.app
            :asset-path "https://localhost:4443/out/out" ;;Super important!
            :output-to "out/app.js"}}]}
```

### 4. src/my/app.cljs
とりあえずアラートだけ出す

```clj
(ns my.app)
(js/alert "hello,world!")
```

## 開発ビルド

0. httpsサーバー用のkeystoreを作成する(詳細は[こちらの記事](http://qiita.com/iku000888/items/32a3d96b7a0c912bf0d4)を参照)
1. プロジェクトルートで`boot repl`(ciderユーザーであればcider-jack-in)を実行する
2. REPLで以下の定義済みの2タスクを実行する

```clj
boot.user> (start-jetty!)
;; 2017-09-08 14:36:14.568:INFO:oejs.Server:nREPL-worker-1: jetty-9.2.21.v20170120
;; 2017-09-08 14:36:14.622:INFO:oejs.ServerConnector:nREPL-worker-1: Started ServerConnector@4c492a48{SSL-http/1.1}{localhost:4443}
;; 2017-09-08 14:36:14.625:INFO:oejs.Server:nREPL-worker-1: Started @83324ms
boot.user> (start-figwheel!)
;; Figwheel: Starting server at http://0.0.0.0:3449
;; Figwheel: Watching build - app
;; Compiling "out/app.js" from ["src"]...
;; Successfully compiled "out/app.js" in 16.669 seconds.
;; nil

```

4.ビルドしたjsファイルにアクセスする

- ブラウザを`https://localhost:4443/out/app.js`に向ける
- 証明書エラーが出るので例外として追加する

## Kintone側の設定

1.アプリの設定→JavaScript / CSSでカスタマイズ で前項でアクセスしたurlを指定する

![Selection_109.png](https://qiita-image-store.s3.amazonaws.com/0/124830/08990119-9eb9-daff-976a-17637221c82f.png)

2.アプリのページにアクセスする。アラートが表示されれば成功

3.cljsのソースコードを編集して保存すると、その度に最新のコードが実行されることが確認できる。


## cljs-repl

REPLに戻って`(cljs-repl!!)`を実行すると、REPLがブラウザに繋る。

## リリースする

- コマンドラインから`boot release-build`を実行する
- 最適化された単一のjsファイルが出力される。

## KintoneのJavaScript API を利用する

- そのまま呼び出すとリリースビルドの際に壊れてしまう
- 対策をしてあるラッパーライブラリである[cljs-ktn-trumpet](https://github.com/iku000888/cljs-ktn-trumpet)を利用する