Search code examples
clojureclojurescriptleiningenreagent

Emitting Hiccup controls from CLJ that call CLJS functions


It seems like this should be simple, and I thought it was... until I switched from running Figwheel to running a JAR file and it stopped working.

The issue can be reduced to a pretty simple example:

Make a new app called "buttontest" using the Leiningen "Reagent" template.

Add some script to core.cljs, right below the "ns" declaration:

(defn greet [] (js/alert "Hi!"))

Add a static button in handler.clj:

(defn loading-page [] (html5 (head) 
 [:body {:class "body-container"} mount-target
  ;v v v INSERTED THIS
  [:button {:onclick "buttontest.core.greet()"} "Say Hello"]
  ;^ ^ ^
  (include-js "/js/app.js")]))

Do a "lein cljsbuild once" and a "lein figwheel." Browse to the site. The "Say Hello" button will trigger an alert when clicked.

Back in the shell, do a "lein uberjar" and run the resultant .JAR file using Java. Browse to the site. The "Say Hello" button will do nothing when clicked. The console shows "buttontest is undefined."

I've tried various things (tinkering with / removing the namespace qualification in the "onclick" attribute, manually including other .JS files, etc.) without luck. I feel like I'm missing something obvious.

Any ideas? Thanks.


Solution

  • Try giving your greet function the export meta flag:

    (defn ^:export greet ...)
    

    I imagine :advanced compilation optimizations mangles the namespace/function name, and :export prohibits that (or something like this).