高速!Clojure Web 開発入門

34
高速! Clojure Web 開発入門 2016/07/21 Nishi-Shinju-Clojure #0 堤 一樹

Transcript of 高速!Clojure Web 開発入門

Page 1: 高速!Clojure Web 開発入門

高速!Clojure Web 開発入門

2016/07/21

Nishi-Shinju-Clojure #0

堤一樹

Page 2: 高速!Clojure Web 開発入門

自己紹介

Page 3: 高速!Clojure Web 開発入門

The RedMonk Programming Language Rankings: January 2016http://redmonk.com/sogrady/2016/02/19/language-rankings-1-16/

Page 4: 高速!Clojure Web 開発入門

本日話す内容

Clojure / Script に興味があるという人は増えている印象だがWeb アプリケーション採用事例はあまり聞かない...• 採用事例:

• CircleCI (Clojurescript)

• kawasima-san products• job-streamer, back-channeling, axebomber-clj etc.

• Clojure / Script で作ったはいいけど保守できる人がいない

Clojure / Script 開発者の裾野を広げたい• Clojure / Script を採用する利点としてWeb 開発の高速さを紹介

• component / duct を例に紹介

Page 5: 高速!Clojure Web 開発入門

本日話す内容

component / duct• component / duct とは

• RDD (REPL Driven Development)

• 他のライブラリ / ツールとの組み合わせ• figwheel

• garden

• reagent

Clojure / Script によるWeb アプリケーション開発サイクル

cljc (Reader Conditionals)

Page 6: 高速!Clojure Web 開発入門

component / duct とは

component - https://github.com/stuartsierra/component• アプリケーションの状態を一元管理するためのフレームワーク

duct - https://github.com/duct-framework/duct• component 上にWeb アプリを構築するためのフレームワーク(プロジェクトテンプレートと少量のライブラリ)

• 12-factor app に従ったアプリケーション構築が可能

Page 7: 高速!Clojure Web 開発入門

component / duct とは component を使わない場合

• Web アプリのような多数の状態を持つアプリケーションを atom / ref で構築すると...• 状態が散らばりどこを参照しているのか分からなくなる

• 状態間の依存関係によりリセットが上手くいないことも

atom atom

atomatom

atom

ref

ref

ref

ref 参照

依存

Page 8: 高速!Clojure Web 開発入門

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

Page 9: 高速!Clojure Web 開発入門

component を使った場合• 各コンポーネントにライフサイクルを定義できる

• ライフサイクルと依存関係から適切にソフトウェア全体の状態を適切に初期化・リセットできるようになる

component / duct とは

状態

ring-jetty-component

状態

db-component

start 設定(handler含む)からjettyサーバ起動起動したサーバは状態として保持

stop 状態として保持されたサーバを停止handlerも破棄

start 設定(handler含む)からDBへ接続接続情報は状態として保持

stop DBとの接続解除接続情報も破棄

Page 10: 高速!Clojure Web 開発入門

component / duct とは実際の定義例

system-map定義

component間の依存関係

from job-streamer-control-bus - https://github.com/job-streamer/job-streamer-control-bus

Page 11: 高速!Clojure Web 開発入門

component / ductとは

component FW 上で ring-clojureのアプリを構築するためのライブラリ(コンポーネント)+ プロジェクトテンプレート• ミドルウェア定義(handler)とルート定義(endpoint)をコンポーネント化

• その他 figwheel(後述)等による開発プロセスもコンポーネント化

• コンポーネント初期化時の設定を共通設定 / 環境依存設定に分けて定義することで 12-factor app に従ったアプリケーションを簡単に構築できる

Page 12: 高速!Clojure Web 開発入門

component / ductとは handler component 実際の定義例

ミドルウェア定義

定義を元にハンドラをコンポーネント化

Page 13: 高速!Clojure Web 開発入門

component / ductとは endpoint component 実際の定義例

ルート定義(compojure)

ルート定義を元にエンドポイントをコンポーネント化

Page 14: 高速!Clojure Web 開発入門

component / ductとは 12-factor app に従い環境依存の設定は環境変数に切り出す

環境依存する設定(及びデフォルト)➡環境変数として設定 / 取得

環境に依存しない設定➡ハードコーディング

マージした設定を元にコンポーネントを生成して起動

Page 15: 高速!Clojure Web 開発入門

component / duct での RDD

RDD (REPL Driven Development)

component / ductで構築したWeb アプリケーション操作は全てClojure REPL から実行可能• 初期化(設定読み込み)

• 起動

• 停止

• リセット

• ...

Web アプリケーションの変更をすぐに確認可能

Page 16: 高速!Clojure Web 開発入門

起動

component / duct での RDD

Page 17: 高速!Clojure Web 開発入門

component / duct での RDD

リセット

Page 18: 高速!Clojure Web 開発入門

component / duct での RDD

RDD に組み合わせると便利なライブラリ• eftest - https://github.com/weavejester/eftest

• テストコード検索 / テストランナー

• REPL から実行可能

• alembic - https://github.com/pallet/alembic• project.clj(leiningenによるプロジェクト定義)の再読み込み

• 依存ライブラリを追加 / 変更した際に即反映できる

Page 19: 高速!Clojure Web 開発入門

他のライブラリ / ツールとの組み合わせについて

garden – https://github.com/noprompt/garden• Clojureの list から cssを生成するライブラリ

• Clojure / Script 両対応のため、cljsに直接埋め込むことも可

Page 20: 高速!Clojure Web 開発入門

他のライブラリ / ツールとの組み合わせについて

reagent - https://github.com/reagent-project/reagent• A simple ClojureScript interface to React.

• hiccup 記法で React.jsの VDOM が表現できる

Page 21: 高速!Clojure Web 開発入門

他のライブラリ / ツールとの組み合わせについて

figwheel - https://github.com/bhauman/lein-figwheel• cljsのビルドとブラウザへのホットロードを行う leiningen plugin

• duct より figwheel-component が提供されている

• 前述の garden もコンポーネント化することで、cssビルド➡ jsビルド➡ js / cssブラウザプッシュという流れが実現できる

styleclj

Page 22: 高速!Clojure Web 開発入門

以上のライブラリを組み合わせると下記が全て REPL から実行可能になる• サーバサイドロジック(clj)の変更とブラウザでの確認

• js(cljs)の変更 / ビルドとブラウザでの確認

• css(clj)の変更 / ビルドとブラウザでの確認

Clojure / Script によるWeb アプリケーション開発サイクル

Page 23: 高速!Clojure Web 開発入門

Clojure / Script によるWeb アプリケーション開発サイクル

REPL 起動

Page 24: 高速!Clojure Web 開発入門

Clojure / Script によるWeb アプリケーション開発サイクル

Remote REPL接続

Page 25: 高速!Clojure Web 開発入門

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

Page 26: 高速!Clojure Web 開発入門

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

Page 27: 高速!Clojure Web 開発入門

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

Page 28: 高速!Clojure Web 開発入門

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

Page 29: 高速!Clojure Web 開発入門

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)

Page 30: 高速!Clojure Web 開発入門

以降は下記の手順を繰り返すだけで開発可能1. clj, cljsファイル修正

2. REPL からリセット

3. ブラウザ確認

依存ライブラリを増やす場合• project.cljを修正して REPL より alembic/load-project

複雑なロジックに対してテストを追加した場合• テストコードを追加して REPL より eftest/find-tests, eftest/run-tests

後は “REPL を切ったら負け” という思いで開発する

Clojure / Script によるWeb アプリケーション開発サイクル

Page 31: 高速!Clojure Web 開発入門

cljc (Reader Conditionals)

JVM / Javascriptクロスプラットフォームを実現する仕組み• cljcファイルは Clojure / Script のいずれからも読み込める

• コード中のプラットフォーム依存部分をReader Conditionalsにて切り替え可能

• 精査、ユーティリティなどを Clojure / Script で共通化できる

JVM / jsで切替

Page 32: 高速!Clojure Web 開発入門

cljc (Reader Conditionals)

components

figwheel-component

server-component

handler-component

endpoint-component

garden-component

reagent

cljc(utility, validation,

style...)

clj cljs

duct

参照

Page 33: 高速!Clojure Web 開発入門

How to start

duct がプロジェクトテンプレートを提供• プロジェクト作成時にオプションで cljsやexample endpoint の追加などが行える

• プロジェクト生成後も leiningenプラグインから endpoint や component の追加が可能

Page 34: 高速!Clojure Web 開発入門

まとめ

Clojure / Script をWeb 開発に採用すれば...• component / duct による状態の一元管理により簡潔なWeb アプリケーションを構築出来る

• REPL による高速な開発プロセス

• cljcによるクロスプラットフォームでのコード共有が可能

Try Clojure!