[CLJS-101] Node fails with :whitespace, works with :simple Created: 17/Nov/11 Updated: 29/Sep/12
Running the example from http://mmcgrana.github.com/2011/09/clojurescript-nodejs.html. Node fails if using :whitespace optimizations, but works when using :simple. The problem seems to be missing object literals.
The source is:
Here is the compilation that results in the broken code:
When changing the optimizations to :simple, however, it works:
The offending line 487 in the :whitespace code:
In the working :simple code, the corresponding lines looks like this:
If I fix that by adding a line that creates the object, I get another error on line 901:
In the working code, it looks like this:
And if I fix that, I get another error on line 975:
The working code:
|Comment by David Nolen [ 19/Apr/12 11:49 PM ]|
I'm not sure how to fix this since the implementation of goog.provide has no meaning in Node.js. As a compromise perhaps we should complain if you try to target node with :whitespace optimizations?
|Comment by Ulrik Sandberg [ 20/Apr/12 5:50 AM ]|
Sure, that would probably be sufficient to point the user to what the problem really is.
Perhaps it's obvious to everyone else that :whitespace doesn't make sense for Node, but it wasn't to me. But I can now deduce that :simple maybe resolves all provide/require into a single file, whereas :whitespace is an intermediate format that is not applicable for Node.
|Comment by David Nolen [ 20/Apr/12 11:29 AM ]|
I don't think it's obvious at all and many people have encountered this issue.
|Comment by Tom Jack [ 16/Aug/12 2:54 AM ]|
Something that seems to work is
Does this cause any problems other than forcing e.g. ;module.exports = _cljsGlobal_.mori; in whitespace mode?
|Comment by David Nolen [ 16/Aug/12 8:30 AM ]|
Using with is probably not an acceptable solution.
|Comment by David Nolen [ 28/Sep/12 10:08 PM ]|
nclosure actually sounds kind of promising! Do we need to do anything more then recommend that people install nclosure if they want to work :whitespace or :none for the optimization level? If the nclosure approach is simple enough we could perhaps duplicate the strategy?
|Comment by Paul deGrandis [ 29/Sep/12 5:27 PM ]|
Haha I deleted the comment after I started digging into the code. I'll try to capture my adventure here.
CLJS's node compat layer is built in the opposite direction as nclojure - that is, we provide an externs file for node, and assume interop will happen that way.
My hypothesis was: I can use the nclosure stuff, but allow ALL dispatching to go to closure (since we have externs file), which very well may call node stuff in the end. The small shim would allow for skirting around the issues described here.
I hacked together the js files and copied the result in to my CLJS-compiled-JS file. All looked good except - the nclosure JS code needs to be inserted into the file before compilation happens. The nclosure stuff redefines core goog interactions, which is why it works. Technically, we could do a preamble hook when we're gathering all the the files together (much like how main-cli-fn is at the tail of all files).
That said, when inserted into the right spot, it prevents the errors.