Capitalize: Lessons Learned
Capitalize was a small (tiny really) project to practice ClojureScript. I think I have learned enough to justify a blog post. Since ClojureScript is basically Clojure with a few differences I am focusing on tools and libraries.
This is not going to be a whiny rant. ClojureScript a great language to write web-based applications. It is a Lisp, it has great support for immutable data and it enables some sort of parallelism. But getting started and then getting productive with ClojureScript is not as easy as Clojure. If you are going to learn ClojureScript, expect a rough start. It will be worth the pain.
I am assuming you are using Leiningen. If you are not, please do.
Configuring ClojureScript Is Not a Walk in the Part
When you are working with Clojure, Leiningen takes care of compilation for you. When you are working with ClojureScript you typically want to configure three builds; an unoptimized dev build, a test build and a fully optimized production build. You also need to configure environments these builds are embedded into.
All of this is well documented. I had help from #clojurecript on FreeNode but all issues I had could have been googled somehow.
You will get error messages like this:
Compiling "target/cljs/test/capitalize_test.js" from ["src" "test"]... Error in file: "/.../capitalize/target/cljs/test/capitalize_test.js" ERROR: cemerick.cljs.test was not required. You can resolve this issue by ensuring [cemerick.cljs.test] appears in the :require clause of your test suite namespaces. Also make sure that your build has actually included any test files. Also remember that Node.js can be only used with simple/advanced optimizations, not with none/whitespace. [ReferenceError: goog is not defined]
I had indeed :required [cemerick.cljs.test :as t], so I was stroking my beard thinking what did I do wrong? If I read past the third paragraph I would know it’s because I was using nodejs with :none as optimization level.
Good news is, once you configure your project, you won’t need to change it often.
ClojureScript Doesn’t Lend Itself to TDD Too Well
Doing TDD requires a lot of switching between code and tests, running the tests in between. ClojureScript compiler does incremental compilation and it is reasonably fast. But when you compile all three builds, because you can’t start cljsbuild with specific builds, each time you change something you need to wait a while.
Good news is front-end applications tend to be UI heavy and UI doesn’t need to be unit tested.
I Was Not Disappointed
If you are trying to learn ClojureScript and you are frustrated because something doesn’t work the way you think it should, just remember these:
- It is probably documented. Check the wiki, then the mailing list.
- Read all of the error message, especially the 4th paragraph. (see above)
- Try IRC: #clojurecript on FreeNode. Paste your project.clj and be specific.
|||I guess this can be fixed using Leiningen profiles. I’ll try that in future projects.|
If you have any questions, suggestions or corrections feel free to drop me a line.