LESS を Maven プラグインでコンパイル - lesscss-maven-plugin を使ってみる
最近になって LESS なる CSS 拡張メタ言語 があることを知った。
LESS に関する細かい話は省略するとして、LESS はブラウザで動的にコンパイルしてスタイルに反映することができる。
ただ、あまりブラウザであれこれやり過ぎるとレンダリングが遅延して UX が損なわれてしまう可能性もあるので、サーバでできる部分(コンパイル)は極力サーバでやっておくべきだと思う。
Node.js なんかだとサーバサイドでの動的コンパイルも可能*1なようだけど、どうせなら静的コンテンツとして扱えるように事前にコンパイルしたいところ。
ということで、Maven 大好きな自分としては「Maven でやってしまえば開発者もいちいち LESS のコンパイルのこと意識しなくてもいいよね!」と考えるわけですね。
プラグインを探してみる
Google 先生に聞いてみたところ、なんかいろいろと似たようなのが湧いて出てきた。
その中でも、Central Repository にも上がっていて、「公式」と謳われている org.lesscss:lesscss-maven-plugin を使うのが一番確実っぽい。
lesscss-maven-plugin は、元々 Codehaus のプロジェクトだったものが lesscss.org の公式 Maven プラグインとして採用されたプロジェクトのよう。
ただ、この lesscss-maven-plugin、せっかく「公式」と謳われているのに検索順位が低い。残念…。
lesscss-maven-plugin を使ってみる
基本的な使い方は 公式の GitHub を見ればいいと思う。
公式の書き方だとちょっとイケてないので自分なりに記述することにする。
lesscss-maven-plugin の設定
<project> ... <build> ... <plugins> ... <plugin> <groupId>org.lesscss</groupId> <artifactId>lesscss-maven-plugin</artifactId> <version>1.3.0</version> <executions> <execution> <goals> <goal>compile</goal> </goals> </execution> </executions> <configuration> <outputDirectory>${project.build.directory}/.generated/webapp/css</outputDirectory> </configuration> </plugin> ...
コンパイルされた LESS (=css) は自動生成ファイル用のディレクトリに出力。
compile ゴールはデフォルトでは process-sources フェーズにマッピングされている。
maven-war-plugin の設定
lesscss-maven-plugin の設定だけでは war に含めることができないので、maven-war-plugin の設定も合わせて行う。
... <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.1.1</version> <configuration> <webResources> <resource> <directory>${project.build.directory}/.generated/webapp</directory> </resource> </webResources> </configuration> </plugin> ...
webResources で、自動生成ファイルも war に含めるように設定。
less ファイルを適当に用意
less ファイルの所定のディレクトリは src/main/less となってる。
src/main/less/sample.less を適当に作成。
@color: #ffffff; @bgcolor: #000000; @bordercolor: #7f7f7f; @precolor: #404040; .rounded-corners (@radius: 8px) { border-radius: @radius; -webkit-border-radius: @radius; -moz-border-radius: @radius; } body { color: @color; background-color: @bgcolor; } pre { .rounded-corners(); background-color: @precolor; border-style: dotted; border-width: medium; border-color: @bordercolor; padding: 7px; margin: 5px; }
コンパイルしてみる
$ mvn lesscss:compile ... [INFO] ------------------------------------------------------------------------ [INFO] Building lesscss-maven-plugin-sample Maven Webapp 1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- lesscss-maven-plugin:1.3.0:compile (default-cli) @ lesscss-maven-plugin-sample --- [INFO] Compiling LESS source: sample.less... [ Envjs/1.6 (Rhino; U; Windows 7 x86 6.1; en-US; rv:1.7.0.rc2) Resig/20070309 PilotFish/1.2.13 ] [INFO] Compilation finished in 1782 ms ... $ cat target/.generated/webapp/css/sample.css
body { color: #ffffff; background-color: #000000; } pre { border-radius: 8px; -webkit-border-radius: 8px; -moz-border-radius: 8px; background-color: #404040; border-style: dotted; border-width: medium; border-color: #7f7f7f; padding: 7px; margin: 5px; }
ちゃんと CSS ができる。
war を作ってみる
$ mvn package ... $ unzip -l target/lesscss-maven-plugin-sample.war *.css Archive: target/lesscss-maven-plugin-sample.war Length Date Time Name --------- ---------- ----- ---- 276 xx-xx-xxxx xx:xx css/sample.css --------- ------- 276 1 file
ちゃんと war にも含まれまる。
サンプル置き場
今回作成しているサンプルの完全なコードは GitHub に上げてみた。
動かす場合は、
git clone https://github.com/tm-senda/lesscss-maven-plugin-sample.git
cd lesscss-maven-plugin-sample
mvn package run:jetty
として*2、http://localhost:9080/index.jsp にアクセスするだけ。
Eclipse でも m2e と m2e-wtp が入っていればビルドして WTP で起動するだけで、特に意識することなく実行できるようになっている。と思う。
lesscss-maven-plugin における現状 (version:1.3.0) の問題点
こんな感じで便利な lesscss-maven-plugin だけど、一部使い勝手に支障のある部分がある。
m2e-wtp が自動生成されたファイルの更新を検知してくれない
less ファイルを保存してビルドすると、less ファイルのコンパイルはちゃんと走ってくれるのだけど、m2e-wtp がそれを検知できていないようで、コンパイルされた css ファイルを ${project.build.directory}/m2e-wtp/web-resources 以下にコピーしてくれない…。
対応としては、
など。釈然としない…。
LESS コンパイル時のファイル排他ロックが残念
前記の問題点があったので Eclipse でのホット・リロードをあきらめて、jetty で実行するようにしてみたところ発覚。
jetty は静的ファイルを read-only で開いたままにしているのに対し、lesscss-maven-plugin で LESS をコンパイルする時に書き込み対象ファイルの完全なロックを取得しようとするため、
[ERROR] C:\Users\tm-senda\git\lesscss-maven-plugin-sample\src\main\less\sample.less [0:0]: Error compiling LESS source java.io.FileNotFoundException: C:\Users\tm-senda\git\lesscss-maven-plugin-sample\target\.generated\webapp\css\sample.css (要求された操作はユーザー マップ セクションで開いたファイルでは実行できません。) at java.io.FileOutputStream.open(Native Method) at java.io.FileOutputStream.(FileOutputStream.java:212) ...
と、残念なことになってしまう。
これはプラグイン側の対応が必要…。