Problem following the DimpleJS recipe from the cookbook (only in production mode)


#1

I have tried to follow the DimpleJS recipe from the Om cookbook, but when running the production-built version of the code, the charts never render and I get (in stead) an “Uncaught TypeError: Cannot read property ‘Fd’ of undefined” error on the console. The only change I have done to the original code is wrapping the om/root expression in a main function (like the default one that’s generated) and adding a few dependencies as imports in index.html.

This is the source code that the Chrome debug console shows, and the error is supposed to be on line 86. In this particular example, I have simply moved the root statement outside the main function (no effect).

I have also made another variant using Google Charts that displays the same error (“Uncaught TypeError: Cannot read property ‘bg’ of undefined” on line 27).

The weirdest thing is that everything works fine in development mode!

Any help would be greatly appreciated.


#2

I’m guessing here, but one of the differences between development and production is that the Google Closure compiler will optimize away unused code. When using external javascript libraries this becomes a bit more complicated, you have to make sure you have a corresponding and correct “externs” file, listing all the identifiers in the js lib that should not be removed.

I’d start by looking around if anyone has already created an externs file for DimpleJS.


#3

Thanks! That would explain the issues with DimpleJS, but would it also explain the problems with Google Charts? Shouldn’t the Google Closure compiler automatically grok Google’s own libraries?

Also, what does such an externs file look like and where do I put it once I have it?

Tried a build with :optimizations :whitespace and that actually fixed the issue at least for Google Charts.


#4

This is already explained better elsewhere, these two blog posts are the top hits on google for “clojurescript externs”.

Long story short: first check if the package you’re using is on CLJSJS, in that case you can just list it as a dependency in leiningen and the externs is taken care of for you. It seems at least DimpleJS is listed there.

Otherwise an externs file is just a javascript file that contains all identifiers with empty definitions:

// externs/waypoints.js
jQuery.prototype.waypoint = function(handler) {};

and you tell Clojurescript where to find it in project.clj

             :prod {:source-paths ["src/cljs"]
                    :compiler { ...
                               :optimizations :advanced
                               :externs ["externs/jquery-1.9.js"
                                         "externs/waypoints.js"]}}

The problem will go away with :optimizations :whitespace since in that case only whitespace is stripped out, so dead code elimination does not happen.


#5

Thanks for clearing that up! I guess moving to DimpleJS may be a good idea then, given that there is no CLJSJS package for Google’s Charts.


#6