Closed jcollum closed 11 years ago
Hey Justin,
You have to start thinking about IDs instead of URLs. :)
The css! plugin defers resource resolution to curl, and, therefore, uses the same lookup rules as modules. Since curl assumes that modules are referenced by ID, the css! plugin assumes you are handing it IDs, too.
However, the leading slash in '/localcss/style.css' eliminates the possibility that it has been handed an ID because IDs don't start with slashes. Instead, it assumes you gave it a URL and skips all the module ID-to-URL resolution rules.
Hm, it seems there's a bug in the current master branch that prevents minified jquery from being used as a preload. The dev branch seems to work, though, according to some quick tests. (There were some changes made to this code.)
Use the dev branch and try this:
<script>
curl = {
baseUrl: "/lib", // you should consider pointing this to your app code, instead
paths: {
localcss: "../css",
localjs: "js",
util : "js/util",
socket: "socket.io",
jquery: '//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.min'
},
preloads: [
'curl-debug.js', // did you move this to the root?
'jquery'
]
};
</script>
<script src='/lib/curl.js'></script>
<script>
curl([
'js!bacon.js',
// !order needs to be specified on all scripts that need ordering. what else needs it here?
'js!underscore-min!order', // you should probably be using lo-dash instead
'js!socket/socket.io.js',
'css!localcss/style.css'
])
.then(function success(){ /*...*/ });
</script>
I suspect the error came from the jquery issue, not the css resource, btw.
-- John
Let me know if this fixes the problem, Justin. Please close the issue if it does. :)
You have to start thinking about IDs instead of URLs. :)
Well, I am, but I don't see the relevance here -- why would I be thinking in terms of IDs for plain js and css files? All the things I'm loading in this example are 3rd party js files or my own css.
I'll try your suggestions and let you know.
Actually I'm wondering if this is a bug in .next
. I'm doing this, essentially:
curl(['js!nonAMD.js'])
.next(['dep1', 'dep2', 'dep3'], function (dep1, dep2, dep3) {
// do something before the dom is ready
})
Code looks like this:
script
curl = {
baseUrl: "/js",
paths: {
app: "./app",
jquery : '//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.min',
lib : "./lib"
},
pluginPath: 'lib/curl/plugin',
preloads: [ 'lib/curl/debug.js', 'jquery' ]
};
script(src='/js/lib/curl.js')
script
moduleLoadError = function(err) {console.log("load config or logger failed: " + err.message);}
curl([
'js!lib/bacon.js',
'js!lib/underscore-min',
'js!/socket.io/socket.io.js'
])
.next(['app/config', 'lib/jslogger.min'],
function(Config, Logger){ alert('config'); window.config = new Config(); window.logger = Logger; window.logger.useDefaults();})
The window.config object is never setup. However if I do this:
curl(['prev/config', 'lib/jslogger.min'],
function(Config, Logger){ alert('config'); window.config = new Config(); window.logger = Logger; Logger.useDefaults();})
the window.config
is set up correctly. I've changed my curl over to use the dev branch version.
Did you try using the error handler on the .next()?
curl([
'js!lib/bacon.js',
'js!lib/underscore-min.js',
'js!/socket.io/socket.io.js'
])
.next(['app/config', 'lib/jslogger.min'],
function(Config, Logger){ alert('config'); window.config = new Config(); window.logger = Logger; window.logger.useDefaults();}
moduleLoadError
);
Yeah, I added this line:
.next(['css!/css/main.css'], (function() {
return console.log('css load complete');
}), moduleLoadError)
And got an error. Here's the debug:
curl getDeps return: Promise {then: function, resolve: function, reject: function, progress: function, id: ""…}
curl getDeps arguments: [Promise]
curl fetchDep arguments: ["css!/css/main.css", Promise]
curl toAbsId arguments: ["css!/css/main.css", "", Begetter]
curl toAbsId return: lib/curl/plugin/css!/css/main.csscurl resolvePathInfo arguments: ["lib/curl/plugin/css", Begetter]
curl resolveUrl arguments: ["./lib/curl/plugin/css", Begetter]
curl resolveUrl return: /js/./lib/curl/plugin/csscurl resolvePathInfo return: Object {config: Begetter, url: "/js/./lib/curl/plugin/css"}
curl createResourceDef arguments: [Begetter, "lib/curl/plugin/css", undefined]
curl createContext arguments: [Begetter, "lib/curl/plugin/css", undefined, undefined]
curl createContext return: Promise {then: function, resolve: function, reject: function, progress: function, id: "lib/curl/plugin/css"…}
curl createResourceDef return: Promise {then: function, resolve: function, reject: function, progress: function, id: "lib/curl/plugin/css"…}
curl checkToAddJsExt arguments: ["/js/./lib/curl/plugin/css", Begetter]
curl checkToAddJsExt return: /js/./lib/curl/plugin/css.jscurl fetchResDef arguments: [Promise]
curl getDefUrl arguments: [Promise]
curl getDefUrl return: /js/./lib/curl/plugin/css.jscurl loadScript arguments: [Promise, function, function]
curl loadScript return: <script type="text/javascript" charset="utf-8" async src="/js/./lib/curl/plugin/css.js"></script>
curl fetchResDef return: Promise {then: function, resolve: function, reject: function, progress: function, id: "lib/curl/plugin/css"…}
curl fetchDep return: Promise {then: function, resolve: function, reject: function, progress: function}
curl getDeps return: Promise {then: function, resolve: function, reject: function, progress: function, id: ""…}
curl fixArgs arguments: [Arguments[1]]
curl fixArgs return: Object {id: undefined, deps: Array[0], res: function, cjs: undefined}
load failed: Multiple anonymous defines in url load-libraries.js:6
curl: ********** modules waiting: 1 curl: ********** module waiting: lib/curl/plugin/css
Also tried it from the command line:
curl("css!./../css/main.css", function(){console.log("success");}, function(err){console.log(err.message);})
curl("css!css/main.css", function(){console.log("success");}, function(err){console.log(err.message);})
curl("css!/assets/css/main.css", function(){console.log("success");}, function(err){console.log(err.message);})
All resulted in the Multiple anonymous defines in url
error. From looking at the server logs, it's never requesting the object.
I'll try debugging a bit and see if I can come up with something.
What is "load-libraries.js" and where is it being referenced?
Can you verify that "/js/./lib/curl/plugin/css.js" is the same as this? https://github.com/cujojs/curl/blob/dev/src/curl/plugin/css.js
What is "load-libraries.js" and where is it being referenced?
It's loaded after the curl script tag. Moving it into a script not-src tag didn't change anything.
Can you verify that "/js/./lib/curl/plugin/css.js" is the same as this?
Yep, they match.
What I'm seeing is that the code is going to:
css.js 515: define(/=='curl/plugin/css',==/ { curl.js 1268: _define(args); curl.js 1232 ish: id = args.id; if (id == undef) { if (argsNet !== undef) { argsNet = { ex: 'Multiple anonymous defines in url' }; }
Seems to be hitting argsNet = {ex:}
because the id is undefined. I wonder if it's loading the cram plugin or missing that part.
Does load-libraries.js have a define() call in it? If so, that could be the cause of the problem. Calling define() (without an id) by a script that wasn't requested via curl() would cause that error. The error would occur once another define() is called.
Does load-libraries.js have a define() call in it?
Nope. It looks like:
var loadComplete, moduleLoadError;
moduleLoadError = function(err) {
console.log(" load failed: " + err.message);
};
loadComplete = function(msg) {
return console.log("scripts finished: " + msg);
};
curl(["js!lib/bacon.js", "js!lib/underscore-min", "js!/socket.io/socket.io.js"], function() {
loadComplete("bacon, underscore, socket.io");
window.und = _;
return window.require = curl;
}, function(err){ console.log("bacon, underscore, socket.io" + err.message);})
curl(['css!/css/style.css'], loadComplete("css"), moduleLoadError)
.next(['js!//cdnjs.cloudflare.com/ajax/libs/moment.js/1.7.2/moment.min.js',
'js!//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js'], loadComplete("moment and jquery complete"), moduleLoadError)
.next(['js!lib/modernizr-2.6.2.min.js', 'js!lib/plugins.js',
'js!//cdnjs.cloudflare.com/ajax/libs/d3/3.0.1/d3.v3.min.js'], loadComplete("modernizer, plugins, d3 complete"), moduleLoadError)
.next(['domReady!', 'js!index.js'], loadComplete('index'), moduleLoadError )
.then(loadComplete('all files'), moduleLoadError);
But the domReady! call is throwing a Multiple anonymous defines in url
error. If I take that out the final next loads correctly.
Note that now that I put the css call first (in the second set of loads) it's no longer throwing an error.
jquery is the problem. don't load it using the js! plugin. Also: moment is AMD -- although (grrrr) they are using a named module which means you must map a path to it: moment:"//cdnjs.cloudflare.com/ajax/libs/moment.js/1.7.2/moment.min", jquery://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min""
other notes:
window.require = curl;
: I suspect this is only going to cause
confusion. If you plan to require dependencies from other modules, you
probably want the "local require". You can get a reference to the
local require by including it as a pseudo-module or as an implicit CJS
var to your modules.// pseudo-module define(["require"], function (require) {});
// implicit. CJS-style module define(function (require) {});
Actually, we don't use language abstractions at all. We recommend cujojs/poly to shim older browsers. Result: fewer dependencies and better code longevity.
.then(loadComplete('all files'), moduleLoadError);
: since
loadComplete does not return a function (returns undefined iiuc), you
will see an error when curl() tries to call it.-- John
jquery is the problem. don't load it using the js! plugin
But I'm loading jquery in my preloads, like you suggested. Maybe jquery ui should be in preloads as well? That gets more complicated because one depends on the other.
means you must map a path to it:
Ok, done.
since loadComplete does not return a function
It's up there: loadComplete = function(msg) { ...
I added these lines to curl.js after line 945:
if (def.id !== null && typeof def.id !== "undefined"){
args.ex += "; module: " + def.id;
}
To help me figure out what is happening with the loading. So I then load my page several times. Results for each attempt:
So out of about 30 loads I saw 10% fail on domReady and 10% on lodash. I might be able to sort this out if I could get a better error message -- can you point me to a line of code that I can modify to get a better error out of the Promise? Is that the right direction to go? The lack of informative errors is burning up too much time, I need to improve it. The domReady fail might be a red herring, it's possible.
My curl for bacon, lodash and socket.io looks like:
curl(["js!lib/bacon.js",
"//cdnjs.cloudflare.com/ajax/libs/lodash.js/1.0.1/lodash.min.js",
"js!/socket.io/socket.io.js"],
function() {
loadComplete("bacon, underscore, socket.io");
window.und = _;
return define(function() {
return require;
});
}, moduleLoadError)
Hey @jcollum, were you able to get this working? -- John
I ditched curl a few months ago. Loading problems went away.
I have a css file at :
http://localhost:3001/css/style.css
The line marked will throw a m.a.d. error for all of these variations:
Also tried moving the css file to /styles/style.css and changing the path accordingly, same error.