cljs-build configuration tip: prefer maps over a vector

If you look at the lein cljs-build sample project, you’ll see that it states:

; The :builds option should be set to a sequence of maps.  Each
; map will be treated as a separate, independent, ClojureScript
; compiler configuration.

If you look at the example right below that description, you’ll see that it is actually set as a map of configuration profiles with the configuration name as the key. So what gives?

Both options work, since the convert-builds-map function on cljs-build ends up converting :builds map to a vector if it instead receives a map. Should you just save this step and do it as a vector yourself?

Turns out there is an advantage to having the :builds as a straight map with the profile as the key, than a vector of maps.

Profiles on lein are merged. If globally you declare your :builds as a vector of maps, instead of a map, then when you try to alter just one value on a profile you end up with one more build configuration. If instead :builds is a map indexed by the build id, then lein will just merge both configuration values.

To give an example, suppose you have the following configuration.

:cljsbuild
  {:builds
   {:app
    {:source-paths ["src/cljs"]
     :compiler     {:other :options-here}
                   }}}

Later, on your :profiles section you could change the :source-paths, to do:

:test 
  {:cljsbuild
    {:builds
     {:app
      {:source-paths ["src/cljs" "src/test-cljs/"]
                     }}}}

This would work just fine, with the :source-paths property being merged into the base :cljsbuild configuration.


Published: 2015-07-27

Author

...
Ricardo J. Méndez