Problem calling third-party library from ClojureScript code when advanced optimization used

152 views
Skip to first unread message

Alen Ribic

unread,
Aug 2, 2011, 10:18:39 AM8/2/11
to Clojure
I have the following function in my cljs that is bound to a click
event. It makes a call to an external library via js* as seen in the
last body form of the preview function.

(defn preview []
(let [body-el (dom/getElement "body_id")
preview-el (dom/getElement "preview_pane")
b-txt (.value body-el)
safe "false"]
(dom/removeChildren preview-el)
(dom/appendChild
preview-el
(dom/htmlToDocumentFragment
(js* "new Showdown.converter().makeHtml(~{b-txt},~{safe})")))))

It works fine when the params has optimization set to
{:optimizations :simple}.
However, with when the :optimizations is set to :advanced, it fails
with the following javascript error: "Uncaught TypeError: undefined is
not a function".
I looked into this in a bit more detail and determined that the
undefined part is the .converter in the Showdown namespace.

In an attempt to find the reason behind this outcome, I read the
"Advanced Compilation and Externs" Google Closure doc.
To quote: "Closure Compiler provides a mechanism for declaring that a
name is defined in external code and so should not be renamed. This
mechanism is called the extern. The compiler assumes that externs will
exist in the environment in which the compiled JavaScript will be
interpreted."
http://code.google.com/closure/compiler/docs/api-tutorial3.html#comptoex

Turning my attention to clj/cljs/closure.clj in ClojureScript, I
located the load-externs function that is designed to
support :externs, but unfortunately doesn't seem to be the case yet,
judging by this function doc "... Any function in an extern file will
not be renamed during optimization... TODO: Implement options
described above." and judging by the function code itself.

Firstly, I would like to clarify my understanding if the above is
correct.
If so, what is the current or suggested way to do this in the mean
time?

I thought about keeping the optimization level at
{:optimizations :simple}, however the optimized, or lack thereof, js
file weighs in at over 400K.

-Alen

Alen Ribic

unread,
Aug 2, 2011, 10:31:56 AM8/2/11
to Clojure
Just to add to this. The part that sticks out to me is the way I call
the third-party library function.
It screams at me with a big NO, (js* "new
Showdown.converter().makeHtml(~{b-txt},~{safe})").

Perhaps I should declare (def showdown (js* "Showdown")) and then work
my way through the host interop.

-Al

Alen Ribic

unread,
Aug 3, 2011, 5:54:13 AM8/3/11
to Clojure
Searching the CLJS bug reports, it turns out that the issue has been
reported. (http://dev.clojure.org/jira/browse/CLJS-10)
Additionally, I implemented a *quick-fix* for load-externs function in
clj/cljs/closure.clj and it resolved the problem as expected.

-Alen

--
Science is what you know, philosophy is what you don't know.
-- Bertrand Russell


On Aug 2, 4:18 pm, Alen Ribic <alen.ri...@gmail.com> wrote:
Reply all
Reply to author
Forward
0 new messages