Leiningenの導入(3): 実例で見る使い方

2015/04/09 11:08:20

前回の記事では、Leiningenの基本的な使い方として、以下のコマンドについて説明しました。

  • lein new: 新規プロジェクトの作成
  • lein deps: 依存ライブラリの取得
  • lein repl: REPLの起動
  • lein run: プロジェクトの実行
  • lein test: テストの実行

今回は、これらのコマンドが実際のプロジェクト開発の中でどのように使われるかを見てみます。

具体的には、Luminusフレームワークを使ったWebアプリケーション開発における使い方を見てみます。なお、ここでは執筆時点(2015年4月現在)の最新版(2.2.2)のLuminusを使った例を紹介します。

Luminusフレームワーク

LuminusはWebアプリケーションのためのマイクロフレームワークの1つです。

「フレームワーク」といってもLuminusは非常に小さく、実体はLeiningeテンプレートから生成されるClojureソースコードとprojectファイルのみからなります。projectファイルに書かれた依存ライブラリを自動生成されるコードによってゆるく繋ぐような構成で作られています。

心許ない印象を受けるかもしれませんが、そういった構成になっていることでフレームワーク自体にロックインされることはなく、Luminusで不十分な機能を別ライブラリで導入しやすいという柔軟な利点にもなっています。

それでは、順に見ていきましょう。

新規プロジェクトの作成

前回ご紹介したとおり、Leiningenで新規にプロジェクトを作成するときは、lein newを実行するのでした。

Luminusは独自のLeiningenテンプレートを用意しているので、Luminusを使ってプロジェクトを始める場合はluminusテンプレートを指定してプロジェクトを作成します。

$ lein new luminus example-project

すると、以下のようなディレクトリ構成でファイル・ディレクトリが作成されます(resourcesおよびtargetディレクトリ以下は省略)。

.
├── Procfile
├── README.md
├── env
│   └── dev
│       └── clj
│           └── example_project
│               └── repl.clj
├── project.clj
├── resources
├── src
│   └── example_project
│       ├── core.clj
│       ├── handler.clj
│       ├── layout.clj
│       ├── middleware.clj
│       ├── routes
│       │   └── home.clj
│       └── session.clj
├── target
└── test
    └── example_project
        └── test
            └── handler.clj

srcディレクトリにClojureソースコードを追加していきます。すでに自動生成されている.cljファイルがいくつかありますが、これがLuminusの機能を実現している部分です。testディレクトリには、名前のとおりテストを追加していきます。devディレクトリ以下にあるのは、後述するREPLからのサーバ起動を実現している部分です。

また、Procfileというファイルも同時に作られますが、これはforemanというプロセス管理ツールのためのものです。WebアプリケーションをHeroku等にデプロイする場合は、このファイルに起動時のコマンドを指定します。

依存ライブラリの取得

luminusテンプレートを指定してプロジェクトを作成すると、以下のようなprojectファイルが作成されます。

自動生成されたproject.cljの内容(抜粋)

(defproject example-project "0.1.0-SNAPSHOT"

  :description "FIXME: write description"
  :url "http://example.com/FIXME"

  :dependencies [[org.clojure/clojure "1.6.0"]
                 [ring-server "0.4.0"]
                 [selmer "0.8.2"]
                 [com.taoensso/timbre "3.4.0"]
                 [com.taoensso/tower "3.0.2"]
                 [markdown-clj "0.9.65"]
                 [environ "1.0.0"]
                 [im.chit/cronj "1.4.3"]
                 [compojure "1.3.3"]
                 [ring/ring-defaults "0.1.4"]
                 [ring/ring-session-timeout "0.1.0"]
                 [ring-middleware-format "0.5.0"]
                 [noir-exception "0.2.3"]
                 [bouncer "0.3.2"]
                 [prone "0.8.1"]
                 ]

  :min-lein-version "2.0.0"

  ... (中略) ...

  :main example-project.core

  :plugins [[lein-ring "0.9.1"]
            [lein-environ "1.0.0"]
            [lein-ancient "0.6.5"]
            ]

  ... (中略) ...
)  

Luminusはデフォルトで多くの依存ライブラリを持っています。これらのライブラリの依存関係を解決するにはlein depsを実行します。

$ lein deps

そうすると、依存しているすべてのライブラリの取得が開始されます。

なお、前回の記事に書いたとおり、lein depsは明示的に実行しなくても、その他のコマンド実行時に必要なタイミングで実行されます。

REPLの起動

ここまででライブラリを使う準備ができました。

Luminusテンプレートで作ったプロジェクトでは、これまでのステップですでに動作するWebアプリケーションが起動できる状態になっています。ためしに、アプリケーションの動作を確認してみるために、REPLからサーバを起動してみましょう。LeiningenからREPLを起動するには以下のコマンドを実行するのでした。

$ lein repl

起動に少し時間がかかるかもしれませんが、しばらく待っているとREPLが起動します。

起動してプロンプトが表示されたら、(start-server)と入力してサーバを起動します。サーバが起動し、ブラウザから http://localhost:3000/ にアクセスしてWelcomeページが表示されれば成功です。簡単でしょう?

プロジェクトの実行

上で説明したのはREPLからサーバの起動でした。

Webアプリケーションに限らず、Clojureでのプログラムの開発時には、REPLからプログラムの動作を確認できる状態にしておき、ソースコードを修正しつつ動作を確認するというサイクルになります。

さて、ひと通りWebアプリケーションの開発が進んでサーバにデプロイする場合、WebアプリケーションをREPLから実行するのは一般的ではありません。Clojureプログラムをスタンドアローンで実行する方法はいくつかありますが、Leiningenから起動するのが一番手っ取り早い方法です。

$ lein run

lein runはprojectファイルに:mainオプションで指定された名前空間中にある-mainという名前の関数を探して呼び出すような仕組みになっています。

Luminusの場合は、自動生成されたprojectファイルにデフォルトで<プロジェクト名>.coreという名前空間が指定されています。前回触れたとおり、明示的に名前空間を指定して実行したい場合には-mオプションを使うこともできます。

$ lein run -m example-project.core

テストの実行

最後にテストです。テストはlein testで実行するのでした。

$ lein test                                                                                                                   lein test example-project.test.handler

Ran 1 tests containing 2 assertions.
0 failures, 0 errors.
$

これにより、testディレクトリ以下にあるテストが実行されます。

ただし、Leiningenの起動は決して早くはないので、テストをするたびにこのコマンドを実行するのは開発が進むにつれ厳しくなってきます。

そのため、実際にはlein testをCIサーバで実行するようにするか、あるいは別途Leiningenのプラグインをインストールして、ファイルの更新を監視し、自動的に再テストしてくれるようにするなどしておくのがいいでしょう。

おわりに

今回はLuminusプロジェクトを例にLeiningenの基本的な使い方をおさらいしました。 以上で「Leiningenの導入」シリーズは終わりです。導入編としてはカバーできていないトピックもありますが、それらについては折に触れて別記事を上げていけたらと考えています。