cujojs / curl

curl.js is small, fast, extensible module loader that handles AMD, CommonJS Modules/1.1, CSS, HTML/text, and legacy scripts.
https://github.com/cujojs/curl/wiki
Other
1.89k stars 216 forks source link

error: multiple anonymous defines in url in one of 3 requests #165

Closed jcollum closed 11 years ago

jcollum commented 11 years ago

I'm doing some socket.io development, so I have 3 windows opening the same page. For some reason one of the curl reqs is throwing "multiple anonymous defines in url". Here's a chunk of the stack trace. It's consistent: window A will throw the error while windows B and C won't.

The curl debug trace:

curl f arguments: 
[x, "foxtrot", undefined, undefined]
 curl-debug.js:40
curl f return: 
A {z: function, g: function, e: function, t: function, id: "foxtrot"…}
 curl-debug.js:42
curl S return: 
A {z: function, g: function, e: function, t: function, id: "foxtrot"…}
 curl-debug.js:42
curl m arguments: 
["foxtrot", "foxtrot", x]
 curl-debug.js:40
curl m return: foxtrot curl-debug.js:42
curl k arguments: 
["foxtrot", x]
 curl-debug.js:40
curl O arguments: 
["foxtrot.js", x]
 curl-debug.js:40
curl O return: /js/foxtrot.js curl-debug.js:42
curl k return: 
Object {b: x, url: "/js/foxtrot.js"}
 curl-debug.js:42
curl J arguments: 
[Object, function, function]
 curl-debug.js:40
curl J return: 
<script type=​"text/​javascript" charset=​"utf-8" async src=​"/​js/​foxtrot.js">​</script>​
 curl-debug.js:42
curl V return: 
A {z: function, g: function, e: function, t: function}
 curl-debug.js:42
curl h return: 
A {z: function, g: function, e: function, t: function, id: ""…}
 curl-debug.js:42
curl X arguments: 
[Arguments[2]]
 curl-debug.js:40
curl X return: 
Object {id: undefined, p: Array[0], v: function, o: undefined}
 curl-debug.js:42
module failed to load: Multiple anonymous defines in url localhost:40
curl X arguments: 
[Arguments[3]]
 curl-debug.js:40
curl X return: 
Object {id: "moment", p: Array[0], v: function, o: undefined}
 curl-debug.js:42

And the lines in the curl script that are relevant:

 .next([
       ...
         '/socket.io/socket.io.js. ',
         'js!foxtrot'])

I suspect the real problem is '/socket.io/socket.io.js. ' (looks like a typo, a quick test seems to confirm this fixes it) but it would have been difficult to figure that out from the debug trace.

Would that socket.io line have caused the multiple anonymous defines error? What is an anonymous define? Why is the line where the error is happening so far past the processing of socket.io?

unscriptable commented 11 years ago

Hello @jcollum,

It looks like the socket.io client is not an AMD module. Therefore, you must use a plugin (or moduleLoader) to use it in curl.js. It's hard to tell from the obfuscated source, but it looks like socket.io.js might be aware of a CJS environment. Try one of these:

// use the js! plugin and return the global `io` function
curl(['js!/socket.io/socket.io.js!exports=io']);
// use the cjsm loader as a plugin (loaders can be used as plugins)
curl(['curl/loader/cjsm11!/socket.io/socket.io.js']);

The fact that "/socket.io/socket.io.js" is a page-relative url makes me wonder if you have your paths and/or packages configuration in order. Hmmm, you must be using socket.io as a global, I assume. The CJSM solution won't work in that case since it expects that you are using modules, not globals. Of course, we recommend modules instead of globals unless you're faced with a massive refactor to get rid of the globals. :)

Also, if you were using packages and modules (instead of globals), you could transparently instruct curl.js to use CJSM as the module format:

curl.config({
    packages: [
        { name: 'io', location: '/socket.io/', main: './socket.io', config: { moduleLoader: 'curl/loader/cjsm11' } },
        { name: 'curl', location: 'where-ever/you/put/curl/src', main: '../curl' }
        /* other packages go here */
    ]
})

This would allow you to reference the socket.io module like this:

define(function (require) {
    var io = require('io'); // done!
});

Let us know what you decide to do and if we've resolved your issue!

Thanks!

-- John

unscriptable commented 11 years ago

Fwiw, I can't explain the "1 of 3 requests" thing. Strange.

jcollum commented 11 years ago

Looks like AMD compatible socket.io is on the way... https://github.com/LearnBoost/socket.io-client/pull/453

Much discussion about it though: https://github.com/LearnBoost/socket.io-client/issues/338

Honestly not sure if it's included in 0.9.13 or not, looks like not.

unscriptable commented 11 years ago

Hm, that's from 5 months ago. I just quickly scanned the code and didn't see any "define" in it, so maybe you're right: it's not in 0.9.13? Let me know what you decide to do and how it turns out please. :)

jcollum commented 11 years ago

It seems to be working better after moving the socket client code out of ./node_modules/socket.io/node_modules/socket.io-client/dist into ./assets/lib. I changed the dict entry to be "socket": "/lib/socket.io.js" and load it with 'js!socket'. My best test case for this was to open 4 windows in the browser and switch between them and F5 a lot. Eventually one would fail to load the socket.io module. I can't get it to fail after making the changes.

Maybe whatever server side magic that was getting /socket.io/socket.io.js to resolve to ./node_modules/socket.io/node_modules/socket.io-client/dist/socket.io.js was messing up curl?

unscriptable commented 11 years ago

Glad it's working now. My latest suspicion is that is was failing all the time but the errors were being suppressed somehow. I saw errors being suppressed recently but haven't isolated the reason. Maybe this was happening for you but the error sometimes is not suppressed?

Anyways, I'm going to close this issue, but feel free to keep commenting or reopen it if you feel it's not actually resolved.

jcollum commented 11 years ago

Yeah you can leave it closed, I feel like my workaround is fine. There is something going on here but it's unclear if it's from socket.io or curl.

jcollum commented 11 years ago

In another project I changed the socket io line back to 'js!/socket.io/socket.io.js' (that's what they recommend on their site: <script src="/socket.io/socket.io.js"></script> ) and couldn't reproduce the problem. So... yeah. No idea.

manast commented 11 years ago

I have the same problem if using socket.io 0.9.11 or above, with 0.9.10 it works fine. So some change they did on .11 that breaks curl... If I discover something I will keep you posted.

unscriptable commented 11 years ago

Thx @manast! Let me know.