Valentin Golev
Valentin Golev

Reputation: 10095

Is there a good ClojureScript workflow?

I'm trying to use ClojureScript for a project. To be a happy developer, I need a quick feedback-loop: write some code and see it as soon as it's possible. I'd also love to use REPL in the context of the current page.

I'm using lein-cljsbuild and from the issues I'm having I think I failed to set it up properly.

First of all, compilation time for a small file is too big, even after "JWM warm-up" with :optimizations :simple:

Compiling "resources/public/js/cljs.js" from ["src-cljs"]...
Successfully compiled "resources/public/js/cljs.js" in 8.233018 seconds.
Compiling "resources/public/js/cljs.js" from ["src-cljs"]...
Successfully compiled "resources/public/js/cljs.js" in 5.522989 seconds.
Compiling "resources/public/js/cljs.js" from ["src-cljs"]...
Successfully compiled "resources/public/js/cljs.js" in 8.144354 seconds.

Second, from time to time I get stuff like this:

Compiling "resources/public/js/cljs.js" from ["src-cljs"]...
Compiling "resources/public/js/cljs.js" failed.
Exception in thread "main" java.lang.NullPointerException
at java.util.regex.Matcher.getTextLength(Matcher.java:1140)
at java.util.regex.Matcher.reset(Matcher.java:291)
at java.util.regex.Matcher.<init>(Matcher.java:211)
at java.util.regex.Pattern.matcher(Pattern.java:888)
at clj_stacktrace.utils$re_gsub.invoke(utils.clj:6)

# ... many similar useless lines

at clojure.lang.Var.applyTo(Var.java:532)
at clojure.main.main(main.java:37)

These stacktraces (most of the time related to syntax errors, as I understood from experimenting), are worse than not helpful: not only they provide zero clues about the error, they also stop automatic recompilation. After every such stacktrace I should do these things:

Third thing which I failed to understand is REPL. From the interwebs I've learned how to connect rlwrap lein trampoline cljsbuild repl-listen to the current page. However, every reload, navigation, and syntax error (god forbid you forget to use rlwrap and press an arrow key) in the console makes the REPL completely stuck. I have to restart it (~10 seconds) and reload the page after that, then start again trying stuff out in a friendly environment.

I think, probably someone has figured it all out and has a workflow that works. Please help me set it all up from the start, because I feel like a failed software engineer.

Upvotes: 24

Views: 2190

Answers (5)

t3chn0b0y
t3chn0b0y

Reputation: 554

Check out figwheel! It's like livereload on steroids.
Working with clojurescript and front-end development was never so much fun!
See for yourself (the demo is a bit outdated – it's even better now!)
It not just reloads the page when files are changed – it provides you interactive programming Bret Victor was talking about (I recommend you to watch that talk if you haven't)

Upvotes: 3

Paul Whelan
Paul Whelan

Reputation: 16809

When in development mode turn :optimizations to :none, it makes a huge difference it won't change the initial compile time but any additional changes will only take milliseconds typically.

I have the following in my project.clj

 :cljsbuild {:builds [{;; Directories of interest:
                        :source-paths ["src"]
                        ;; Compiler flags:
                        :compiler {;; Where to save the file:
                                   :output-to "resources/public/js/app.js"
                                   ;; Where to put the output directory
                                   :output-dir "resources/public/js/out"
                                   ;; Optimizations:
                                   :optimizations :none
                                   }}]}

Upvotes: 2

Ming
Ming

Reputation: 4300

compilation time for a small file is too big

Try :optimizations :whitespace. And use lein cljsbuild auto

Second, from time to time I get stuff like this: ......

I haven't met this problem before. It looks like a bug in cljsbuild. Try to change another version maybe. I'm using [lein-cljsbuild "1.0.2"] with [org.clojure/clojurescript "0.0-2156"]. The 1.0.3 doesn't work in my setup.

Third thing which I failed to understand is REPL

In your case the key point is to find a way reloading namespaces without restart REPL or reloading page.

I find load-file is good for this.

My workflow is:

  1. First start REPL: rlwrap lein trampoline cljsbuild repl-listen
  2. Make sure there is (repl/connect "http://localhost:9000/repl") in my code.
  3. Open my page in browser.
  4. Do some test (my-namespace/my-func a b c)
  5. Edit my codes.
  6. In my REPL, run (load-file "path-to-my-file.cljs")
  7. Repeat 4

This is still a pretty annoying workflow. load-file is slow and fragile so sometimes I browser to test. I hope someone can provide a better answer.

Upvotes: 0

tangrammer
tangrammer

Reputation: 3061

I've tried inside Emacs this tool https://github.com/cemerick/austin and works very well as you can see in his demo and screencast.

Have a good development Juan

Upvotes: 2

Dimagog
Dimagog

Reputation: 1925

For me Catnip provides the best dev experience for ClojureScript at the moment.

Upvotes: 5

Related Questions