Saturday, November 26, 2011

Closer to the metal: Clojure, Noir, and plain old Javascript

I am wrapping up a long term engagement over the next five to six weeks that uses Java EE 6 on the backend, and SmartGWT (like GWT, but with very nice commercially supported components) clients. As I have time, I am starting up some new work that uses Clojure and Noir, and it is like a breath of fresh air:

I keep a repl open on the lein project and also separately run the web app so any file changes (including the Javascript in the project) are immediately reflected in the app. Such a nice development environment that I don't even think about it while I am working, and maybe that is the point!

As I have mentioned in previous blog posts, I really like the Clojure Noir web framework that builds on several other excellent projects. Developing in Noir is a lot like using the Ruby Sinatra framework: handles routes, template support options, but it is largely roll your own environment.

4 comments:

mmwaikar said...

Hi Mark,

I also keep a repl open on the lein project and was running the web app using lein run, but it was not recognizing file changes.

Could you please specify how were you running the web app so that it was recognizing file changes.

Thanks,
Manoj.

Mark Watson, author and consultant said...

Hello Manoj,

I assume that you have something like this:

:main myapp.core

in your project.clj so lein run works OK. And something like this in your main program file:


(ns myapp.core
(:use [hiccup form-helpers page-helpers]
ring.middleware.file
noir.core
[noir.response :only [json]]
[clojure.stacktrace :only [root-cause]]
myapp.partials
myapp.segmentcreation
myapp.mongodb
myapp.home)
(:require [noir.server :as server]
[noir.session :as session]
[noir.cookies :as cookies]))

Then the magic Clojure source file reloading is enabled:

(server/add-middleware wrap-file (System/getProperty "user.dir"))

Enjoy!,
Mark

Mark Watson, author and consultant said...

Monoj, my last comment applied to the lein run process auto reloading Clojure source files.

In the repl, I do a (use 'myapp.core :reload-all) to manually reload everything.

Greg said...

Hi Mark,

In regards to:

(server/add-middleware wrap-file (System/getProperty "user.dir"))

Can this reload any clojure source file in the project? Or just source files that match a route request?

Here is the documentation for wrap-file (from github: ring / ring-core / src / ring / middleware / file.clj):


(defn wrap-file
"Wrap an app such that the directory at the given root-path is checked for a
static file with which to respond to the request, proxying the request to the
wrapped app if such a file does not exist.

An map of options may be optionally specified. These options will be passed
to the ring.util.response/file-response function." ...

- Greg