高速!Clojure Web 開発入門
-
Upload
kazuki-tsutsumi -
Category
Technology
-
view
1.358 -
download
1
Transcript of 高速!Clojure Web 開発入門
高速!Clojure Web 開発入門
2016/07/21
Nishi-Shinju-Clojure #0
堤一樹
自己紹介
The RedMonk Programming Language Rankings: January 2016http://redmonk.com/sogrady/2016/02/19/language-rankings-1-16/
本日話す内容
Clojure / Script に興味があるという人は増えている印象だがWeb アプリケーション採用事例はあまり聞かない...• 採用事例:
• CircleCI (Clojurescript)
• kawasima-san products• job-streamer, back-channeling, axebomber-clj etc.
• Clojure / Script で作ったはいいけど保守できる人がいない
Clojure / Script 開発者の裾野を広げたい• Clojure / Script を採用する利点としてWeb 開発の高速さを紹介
• component / duct を例に紹介
本日話す内容
component / duct• component / duct とは
• RDD (REPL Driven Development)
• 他のライブラリ / ツールとの組み合わせ• figwheel
• garden
• reagent
Clojure / Script によるWeb アプリケーション開発サイクル
cljc (Reader Conditionals)
component / duct とは
component - https://github.com/stuartsierra/component• アプリケーションの状態を一元管理するためのフレームワーク
duct - https://github.com/duct-framework/duct• component 上にWeb アプリを構築するためのフレームワーク(プロジェクトテンプレートと少量のライブラリ)
• 12-factor app に従ったアプリケーション構築が可能
component / duct とは component を使わない場合
• Web アプリのような多数の状態を持つアプリケーションを atom / ref で構築すると...• 状態が散らばりどこを参照しているのか分からなくなる
• 状態間の依存関係によりリセットが上手くいないことも
atom atom
atomatom
atom
ref
ref
ref
ref 参照
依存
component を使った場合• ソフトウェアをコンポーネントという単位に分割
• ソフトウェア内の状態をコンポーネント単位で管理
• コンポーネント間の依存関係を定義できる
component / duct とは
状態 状態
状態 状態
ring-jetty-component
db-component
handler-component
endpoint-component
system-map
endpoint-component db-componentに依存
handler-component db-componentに依存service-componentに依存
ring-jetty-component handler-componentに依存
system-using
component を使った場合• 各コンポーネントにライフサイクルを定義できる
• ライフサイクルと依存関係から適切にソフトウェア全体の状態を適切に初期化・リセットできるようになる
component / duct とは
状態
ring-jetty-component
状態
db-component
start 設定(handler含む)からjettyサーバ起動起動したサーバは状態として保持
stop 状態として保持されたサーバを停止handlerも破棄
start 設定(handler含む)からDBへ接続接続情報は状態として保持
stop DBとの接続解除接続情報も破棄
component / duct とは実際の定義例
system-map定義
component間の依存関係
from job-streamer-control-bus - https://github.com/job-streamer/job-streamer-control-bus
component / ductとは
component FW 上で ring-clojureのアプリを構築するためのライブラリ(コンポーネント)+ プロジェクトテンプレート• ミドルウェア定義(handler)とルート定義(endpoint)をコンポーネント化
• その他 figwheel(後述)等による開発プロセスもコンポーネント化
• コンポーネント初期化時の設定を共通設定 / 環境依存設定に分けて定義することで 12-factor app に従ったアプリケーションを簡単に構築できる
component / ductとは handler component 実際の定義例
ミドルウェア定義
定義を元にハンドラをコンポーネント化
component / ductとは endpoint component 実際の定義例
ルート定義(compojure)
ルート定義を元にエンドポイントをコンポーネント化
component / ductとは 12-factor app に従い環境依存の設定は環境変数に切り出す
環境依存する設定(及びデフォルト)➡環境変数として設定 / 取得
環境に依存しない設定➡ハードコーディング
マージした設定を元にコンポーネントを生成して起動
component / duct での RDD
RDD (REPL Driven Development)
component / ductで構築したWeb アプリケーション操作は全てClojure REPL から実行可能• 初期化(設定読み込み)
• 起動
• 停止
• リセット
• ...
Web アプリケーションの変更をすぐに確認可能
起動
component / duct での RDD
component / duct での RDD
リセット
component / duct での RDD
RDD に組み合わせると便利なライブラリ• eftest - https://github.com/weavejester/eftest
• テストコード検索 / テストランナー
• REPL から実行可能
• alembic - https://github.com/pallet/alembic• project.clj(leiningenによるプロジェクト定義)の再読み込み
• 依存ライブラリを追加 / 変更した際に即反映できる
他のライブラリ / ツールとの組み合わせについて
garden – https://github.com/noprompt/garden• Clojureの list から cssを生成するライブラリ
• Clojure / Script 両対応のため、cljsに直接埋め込むことも可
他のライブラリ / ツールとの組み合わせについて
reagent - https://github.com/reagent-project/reagent• A simple ClojureScript interface to React.
• hiccup 記法で React.jsの VDOM が表現できる
他のライブラリ / ツールとの組み合わせについて
figwheel - https://github.com/bhauman/lein-figwheel• cljsのビルドとブラウザへのホットロードを行う leiningen plugin
• duct より figwheel-component が提供されている
• 前述の garden もコンポーネント化することで、cssビルド➡ jsビルド➡ js / cssブラウザプッシュという流れが実現できる
styleclj
以上のライブラリを組み合わせると下記が全て REPL から実行可能になる• サーバサイドロジック(clj)の変更とブラウザでの確認
• js(cljs)の変更 / ビルドとブラウザでの確認
• css(clj)の変更 / ビルドとブラウザでの確認
Clojure / Script によるWeb アプリケーション開発サイクル
Clojure / Script によるWeb アプリケーション開発サイクル
REPL 起動
Clojure / Script によるWeb アプリケーション開発サイクル
Remote REPL接続
Clojure / Script によるWeb アプリケーション開発サイクル
duct-figwheel-component
cljs
garden-component
clj css
js
build
build
ring-jetty-component
db-component
handler-component
endpoint-component
user=> (go)
Remote REPL
Clojure / Script によるWeb アプリケーション開発サイクル
duct-figwheel-component
cljsrequest
garden-component
clj
ring-jetty-component
db-component
handler-component
endpoint-component
index.htmlapp.jsscreen.css
Remote REPLcss
js
Clojure / Script によるWeb アプリケーション開発サイクル
duct-figwheel-component
cljswebsocket
garden-component
clj
ring-jetty-component
db-component
handler-component
endpoint-component
index.htmlapp.jsscreen.css
Remote REPLcss
js
Clojure / Script によるWeb アプリケーション開発サイクル
duct-figwheel-component
cljs
garden-component
clj css
css
js
build
build
ring-jetty-component
db-component
handler-component
endpoint-component
user=> (reset)
Remote REPL
clj cljs
websocket index.htmlapp.jsscreen.cssapp.js push
screen.css push
styleclj
Clojure / Script によるWeb アプリケーション開発サイクル
duct-figwheel-component
cljs
garden-component
clj css
css
js
build
build
ring-jetty-component
db-component
handler-component
endpoint-component
Remote REPL
clj cljsstyle
clj
websocket index.htmlapp.jsscreen.css
:on-jsload(reagent/render ...)
user=> (reset)
以降は下記の手順を繰り返すだけで開発可能1. clj, cljsファイル修正
2. REPL からリセット
3. ブラウザ確認
依存ライブラリを増やす場合• project.cljを修正して REPL より alembic/load-project
複雑なロジックに対してテストを追加した場合• テストコードを追加して REPL より eftest/find-tests, eftest/run-tests
後は “REPL を切ったら負け” という思いで開発する
Clojure / Script によるWeb アプリケーション開発サイクル
cljc (Reader Conditionals)
JVM / Javascriptクロスプラットフォームを実現する仕組み• cljcファイルは Clojure / Script のいずれからも読み込める
• コード中のプラットフォーム依存部分をReader Conditionalsにて切り替え可能
• 精査、ユーティリティなどを Clojure / Script で共通化できる
JVM / jsで切替
cljc (Reader Conditionals)
components
figwheel-component
server-component
handler-component
endpoint-component
garden-component
reagent
cljc(utility, validation,
style...)
clj cljs
duct
参照
How to start
duct がプロジェクトテンプレートを提供• プロジェクト作成時にオプションで cljsやexample endpoint の追加などが行える
• プロジェクト生成後も leiningenプラグインから endpoint や component の追加が可能
まとめ
Clojure / Script をWeb 開発に採用すれば...• component / duct による状態の一元管理により簡潔なWeb アプリケーションを構築出来る
• REPL による高速な開発プロセス
• cljcによるクロスプラットフォームでのコード共有が可能
Try Clojure!