testingclojureclojurescriptcljsbuild

How do I get the direct result of a simple clojurescript compilation?


I want to be able to inject javascript code into my app while testing. Following this line of reasoning, I do the following in a repl.

=> (cljs.closure/build '(swap! my-project.my-namespace.my-atom inc) {})
<= "goog.addDependency(\"base.js\", ['goog'], []);\ngoog.addDependency(\"../x8LL7.js\", [], []);"

I then

=> more out/x8LL7.js 
<= cljs.core.swap_BANG_.call(null,my_project.my_namespace.my_atom,cljs.core.inc);

Yes, it appears that this is what I want. I could be mistaken, but I do not think I need the "base.js" dependency, as it is already included in the running app under test (which is using :simple :optimizations).

My question is, how can I get the content of file out/x8LL7.js? I just want the string that is written to out/x8LL7.js as I have no use for the deps file string that is returned from cljs.closure/build.

If it isn't easy, then I guess I can just parse the returned deps string, open the file myself and then use the content; not a big deal. Still, I was hoping there was a more direct way.


Solution

  • Mostly just a note to myself, but in case someone needs to know, here is how I quick fixed it.

    (def cljs-to-js-dir "_cljs_to_js_out")
    
    (def js-options { :output-dir cljs-to-js-dir})
    
    (defn js-compile [quoted-expr]
      (let [ result (cljs.closure/build quoted-expr js-options)
             file-name  ((re-find #"(/.+\.js)" result) 0)]
        (slurp (str  cljs-to-js-dir "/" file-name))))
    
    (defmacro to-js [expr]
      (js-compile `((fn [] ~expr))))
    

    Using this code, you can then (from the repl) type:

    => (to-js (swap! my-project.my-namespace.my-atom inc))
    <= "(function (){\nreturn cljs.core.swap_BANG_.call(null,my_project.my_namespace.my_atom,cljs.core.inc);\n}).call(null);\n"
    

    I bet you are curious as to why I wrapped the expr(ession) in a immediately called no argument function. It is because cljs.closure/build will optimize away code if it is not actually used. For instance:

    => (js-compile '(fn [a b] (+ a b))) 
    <= ""
    

    however

    => (js-compile '((fn [a b] (+ a b)) 2 3))
    <= "(function (a,b){\nreturn (a + b);\n}).call(null,2,3);\n"
    

    Details aside, (to-js) seems to do what I want.