2017年9月6日水曜日

calvinを使ってhiccupを利用したnodejsアプリを作る方法


やりたかったことを実現できたので、方法を共有します。

背景

前回はlumoを使って、nodejsのアプリをcojurescript(以下cljs)で作りました。
lumo(javaに依存しないclojurescriptビルドツール)でnodejsアプリを作る方法

それはそれで嬉しいのですが、hiccupというhtmlの作成をサポートしてくれるclojureのライブラリを使えれば個人的にさらに嬉しいので、やり方を調べてみました。

lumoを内部で利用しているcalvinというツールを使うことで、hiccupを利用してnodejsのアプリが作れたので、その方法を共有します。

全体像

この流れで説明します。
  1. 環境構築
  2. hiccupに依存したプロジェクトの作成
  3. replで動作確認
  4. プログラムの実行
  5. ビルドして実行
  6. まとめ
  7. 参考

環境構築

nodejsとnpmが使える環境を用意してください。
$ node -v
v8.4.0
$ npm -v
5.3.0

lumoをインストールします。
npm i -g lumo-cljs

calvinをインストールします。
npm i -g calvin-cljs

hiccupに依存したプロジェクトの作成

hiccupを使うためのプロジェクトを作ります。

適当なディレクトリを作ります。
mkdir -p ~/gitprojects/bootstrapped-cljs-practice
cd ~/gitprojects/bootstrapped-cljs-practice

ディレクトリを作れたら、下記のようなproject.cljを作成します。
project.clj
(defproject bootstrapped-cljs-practice "0.1.0-SNAPSHOT"
  :description "A project for my practice how to use bootstrapped cljs."
  :license {:name "MIT license"
            :url "https://opensource.org/licenses/MIT"}
  :dependencies [[hiccups "0.3.0"]]
  :cljsbuild {:builds
              [{:id "dev"
                :source-paths ["src"]
                :compiler {:output-to "out/main-express-sample.js"
                           :main express-sample.core
                           :optimizations :simple
                           :target :nodejs}}]})

上記のproject.cljでhiccupをcljsで使えるようにしてくれているhiccupsを依存関係(dependencies)に設定しています。
buildの記述がないとreplが起動しないため、後の手順で作る src/express_sample/core.cljs用のビルド設定も記述しています。

replで動作確認

下記のコマンドで、hiccupsなどの関連ライブラリがダウンロードされて、replが起動します。
(「lein deps」に似た「calvin deps」コマンドはあるのですが、それは依存関係を表示してくれるだけで、関連ファイルのダウンロードはしてくれないようです。 2017.09.06 時点)
calvin repl


下記のようなコマンドで、hiccupsを通してhiccupの機能を利用できます。
(require '[hiccups.runtime :as h])
(h/render-html [:h1 "hoge"])


しかし、require-macrosはできないようでした。
(require-macros '[hiccups.core :as hiccups :refer [html]])


replでの動作確認により、hiccup(hiccups)を部分的に使えることが分かりました。

プログラムの実行

replで利用できることが分かったので、nodejsのアプリとして利用してみます。
webアプリを作るためにexpressを利用しました。

プロジェクトディレクトリでnodejsプロジェクトを開始し、expressを読み込みます。
cd ~/gitprojects/bootstrapped-cljs-practice
npm init
npm install express --save

expressとhiccupを使ったプログラムを記述します。
src/express_sample/core.cljs
(ns express-sample.core
  (:require [hiccups.runtime :as hiccupstr]))

(def express (js/require "express"))
(def app (express))

(.get app "/"
      (fn [req res]
        (.send res (hiccupstr/render-html
                    [:div
                     [:p "Hello world."]
                     [:a {:href "/sample"} "sample"]]))))

(.get app "/sample"
      (fn [req res]
        (.send res (hiccupstr/render-html
                    [:div
                     [:p "sample page"]
                     [:a {:href "/"} "home"]]))))

(.listen app 3000
         (fn []
           (js/console.log "started-express")))

下記のコマンドで実行できます。
calvin repl -c src -m express-sample.core

http://localhost:3000にアクセスすると、cljsで記述したページにアクセスできます。


ちなみに、上記のコマンドで実行中にcljsファイルを書き換えても、(記事執筆2017.09.06時点では)コマンドを再実行しなければ変更が反映されないようでした。

cljsで作ったプログラムを実行できました。

ビルドして実行

プログラム単体で実行できたので、cljsをjsに変換して、nodejsのアプリとして実行してみます。

下記のコマンドでproject.cljに記述したdevのbuildを実施できます。
(project.cljに記述したbuildのoptimizationsがnoneだとエラーになるので、simpleにしています。)
calvin build dev

ビルドしたファイルの出力先としてout/main-express-sample.jsを指定したため、ビルドしたjsファイルは下記のコマンドで実行できます。
node out/main-express-sample.js

cljsのプログラムを実行した時と同様に、http://localhost:3000にアクセスすると、サンプルページを確認できます。

cljsをjsにビルドし、nodeコマンドで実行できました。

まとめ

nodejs上でlumoを動かし、cljsでhiccup(hiccups)を部分的に呼び出し、hiccupとexpressを利用したnocejsアプリを作成できました。
個人的に感じた利点と欠点を上げるとすると、こうです。

利点
  • nodejsを通してcljsの開発環境を作れる
  • nodejsの環境でcljsに対応したライブラリを部分的に利用できる

欠点
  • cljsに対応したライブラリでも使えない場合がある(usemacroとかは使えなさそうでした)
  • cljsをjsにビルドするのに、まあまあ時間がかかる(今回の例だと数十秒かかりました)

cljs対応のライブラリの利用できる機能が部分的だったものの、個人的にやりたいと思っていたことが達成できて満足です。

共有する情報は以上です。

参考

calvin

0 件のコメント :