Compile your CoffeeScript along with your Clojure

I’m building a Web app with Clojure, and while I’m very interested in ClojureScript, I haven’t had a chance to ramp up on it yet. So when I needed to add some client-side code to my project, I naturally wrote it in CoffeeScript, a little language I’m very fond of.

CoffeeScript is great, but it can be a little annoying to remember to compile my CoffeeScript code to JavaScript every time I make a change. So I figured it’d be nice to have my CoffeeScript code automatically compiled every time my Clojure code is compiled. And since I use the excellent Leiningen to build my Clojure projects, I figured it’d probably be pretty easy to set up.

Turns out, I was mostly right about that, but not entirely. While in the end the code to accomplish this is fairly straightforward, I wasn’t able to figure it out on my own. I ended up posting a question to the Leiningen mailing list. As is typical of the fantastic Clojure community, I received a response from the creator of the tool, Phil Hagelberg. Phil pointed me in the right direction — towards his intriguing library Robert Hooke — but it took a little back and forth, and trial and error, before I actually had everything working.

I thought it’d be helpful to share the end result, so that next time someone wants to do this they can just use my solution as a starting point.

Using Robert Hooke

If you’re using Leiningen 1.7.x, you’ll need to use Phil’s Robert Hooke library — instructions and code are in this Gist:

(I’m having some trouble embedding the Gist, so for now you’ll have to click through.)

This approach is also compatible with Leiningen 2.0.x.

Using Leiningen 2.0.x’s :prep-tasks

According to Phil, this sort of thing is easier with Leiningen 2.0.x:

The gist is that every task in :prep-tasks runs before any
eval-in-project call. This defaults to ["javac" "compile"], but you
can customize it in project.clj. In your case you’d need a
coffeescript task implemented by a plugin, but adding ["coffeescript"]
to :prep-tasks would do the trick, since it would be merged with the
default value.

Unfortunately this is beyond my level of familiarity with Maven — I don’t know how to install a plugin which would implement a CoffeeScript compilation task. If anyone wants to give me any pointers, I’d love to add step-by-step instructions. Until then, the Robert Hooke approach documented above works just fine with Leiningen 2.0.x.