Comments (11)
Hey Toby,
Sorry about the frustration.
What version of curl.js are you using. I assume it's 0.5.4? Also, there should be another error in addition to the "Promise already completed" error. If you're using Chrome dev tools or Firebug, check the Network/Net tabs to see if curl.js tried to fetch a file at the wrong location.
In the meantime, I'll set up a test case to see if your hypothesis is correct: curl can't handle when two module ids that map to the same url are listed in a single dependency list.
-- John
from curl.
Hey Toby,
I created the following gist to try to reproduce the issue. This super simple test case succeeds. Do you see anything with that test case that can be modified to better mimic your project? https://gist.github.com/1695074
Here are some potential gotchas I see from your code snippets. I can't tell from your snippets whether they apply or not, but I thought I'd list them anyways:
a) it looks like you are not using packages, either explicit or implicit. The module id, "eaf.util", looks like it could mean module "util" in package "eaf". "eaf.util" on the other hand is just a top-level module to AMD.
This is fine under simple projects. However, if you start using relative paths within your modules, curl.js won't know what to do. Relative paths need a parent folder or package name to work correctly. Specifying a relative path from a top-level module is not supported by AMD. If you are not using relative paths in your modules, then this is not the problem.
curl.js doesn't currently throw an exception when it hits this situation. We need to fix this.
b) You are naming your modules (e.g. the 'domain.base' id above). This is only recommended for special circumstances: it limits how you can structure your folders and where you can locate your modules. curl.js throws an exception if the id of a module doesn't match the location it was fetched from.
Unfortunately, it's way too easy to mix the concepts of urls and module ids in your paths. For instance, if curl tried to load a module located at "js/my/core" and the core module declares its name as just "my/core", then curl.js will assume it got the wrong module and throw an exception.
The way to fix this is to either set the baseUrl to "js" or to create a path to map "my" to "js/my" (or map "my/core" to"js/my/core" if that's the only module you want mapped). curl.js will look at the map and know that you've specified a special location for that folder (or module).
Better yet: don't name your modules at all. It's a lot easier if you don't.
I hope this message helps!
-- John
from curl.
Thanks for the attention to this issue.
Yes, I'm using version 0.5.4 of curl, and version 11 of chrome browser.
The network tab shows all success. I'm assuming you're thinking there would be a 404 or something. No such "luck," I guess. Here is the stack behind the error:
Uncaught Error: Promise already completed.
-
resolve.rejectcurl.js:237
-
resolvecurl.js:253
-
loadScript.argscurl.js:427
-
fetchDep.then.completedcurl.js:620
-
completecurl.js:243
-
resolvecurl.js:224
-
resolvecurl.js:253
-
loadScript.argscurl.js:427
-
fetchDep.then.completedcurl.js:620
-
completecurl.js:243
-
resolvecurl.js:224
-
resolvecurl.js:253
-
completecurl.js:243
-
resolvecurl.js:224
-
resolvecurl.js:253
-
define.load.orderjs.js:112
-
processjs.js:50
I'm using a mix of AMD and non-AMD modules, as you can see by the reference to js.js. I may not have the problem statement correct (i.e. this issue may be a non-issue). Certainly, your gist seems to indicate this. I tried to complicate your gist to be a bit more like what I'm doing, but still got no errors. But I didn't complicate it to the point of mixing AMD and non, so that may be the root issue, or, that is, how I'm mixing them. I may just post up exactly what I'm doing, but since github is blocked at work right now, it's a little more challenging than a matter of uploading. I'll probably just work around that.
About your second comment, I suppose I could treat eaf as a package, but I don't think not doing so should be an issue.
Ultimately, it may just be that I'm trying to fight this framework without much hope of winning. You see, I rather like j coglan's approach: that you claim dependencies to actual apis, not paths. You tell (configure) the loader where to find those apis, but in your own api, you keep all references to other apis, and leave the physical layout out of it. I didn't really want to abandon his loader, but it seems that AMD is the new way, and for the most part I was just going to start using your wire.js and figured migrating to AMD might be the only way to do so.
Anyway, I guess I'm trying to hold on to what I think is the best of the j coglan (or whomever he may be modeling after) world, and merge that with what's best of the AMD world. He sticks strictly to api, and AMD (helps to) keep everything out of the global space. Therefore, I'm setting a path for all of my apis, with the key being the api, thinking this will allow me to essentially keep path stuff out of my own module dependencies.
Perhaps this is all possible, and I'm tripping up in trying to use so many non-AMD modules. This is another good thing about the approach that j coglan took. Sorry, just saying... more a critique against AMD than curl anyway.
Anyway, thanks again. I'll try to get more detail and either close this and open another issue, or provide something more helpful in this one.
from curl.
Hello Toby,
Thanks for the additional information! Wow, I can't believe that github is blocked at work. How can you get anything done? :)
Anyways, mixing AMD and non-AMD files/modules is not easy. I apologize for the lack of documentation in this area. Here are some things that come to mind:
a) The js! plugin has been updated since 0.5.4. The version in the dev branch on http://github/cujojs/curl has one important bug fix (#30) and a new feature. Now it will allow you to make some non-AMD modules act like AMD. If you specify the !exports=global_var option at the end of the resource id, it will pass that to dependent modules:
define(['js!my/nonAMDmodule.js!exports=some_global_var', function (some_global_var) { /* ... */ });
b) Non-AMD modules require the .js extension in version 0.5.4. IIRC, the plugin works a bit differently in 0.6, but I'd plan to include them, anyways.
c) If your non-AMD modules depend on AMD modules, you can get into bad situations fast. The !order option on the js! plugin does not wait for AMD modules! For this reason, it's probably easier to migrate the "leaf nodes" in your dependency graph before the core files.
d) There are a few third-party plugins that help deal with these issues. I have not tried them with curl.js, but the depend! plugin looks like it should work:
depend!: https://github.com/millermedeiros/requirejs-plugins/blob/master/src/depend.js
use.js: http://tbranyen.com/post/amdrequirejs-shim-plugin-for-loading-incompatible-javascript
wrap.js: http://geddesign.com/post/16561192290/introducing-wrap-js
It'd be great to see your code (or a close facsimile) so we could offer more/better help.
Coglan's approach is interesting. It makes sense to me. After all, paths are just another implementation detail that should be abstracted/hidden. That sounds similar to the approach I had before @briancavalier introduced me to IOC. My focus was on the APIs. APIs are still important when using IOC, of course, but because you've moved the details of the APIs to a small set of declarations and adapters, it's easier to deal with shifting APIs.
-- John
from curl.
I've seen some people abstract/contain the non-AMD dependencies into one (or more) AMD modules. Inside the AMD container, all of the non-AMD modules are loaded in the correct order. Outside of the AMD container, order no longer matters.
from curl.
Yeah, they switched firewalls and they lost the exception to github. We're mostly a .net shop and I'm the only one that really uses github, so it's a one man battle right now.
Thanks, I'll try the dev branch version and see if that clears it up.
I noticed that about the .js extension requirement.
Might look into that depend! plugin. Thanks for the heads up.
Kind of waiting to see if the man will open up github, so it will be easier to upload, so hopefully soon with a more accurate representation of broken code. I also haven't invested the time to learn github really well--being shamelessly lopsidedly consumerish--so I'll probably be setting things up the hard way.
So you're blaming @briancavalier for corrupting you?:) Did Coglan win you back over from the dark side? It would be nice to see wire not depend on AMD--fall back to seeing if the module is a global, or something. If I can't get this stuff working in fairly short order, there is jsfIoc, but the cujo pack seems like it's got a lot to offer.
About your last comment, yeah, perhaps with some creative packaging, I could wrap all the non-AMD modules in a define or something. Not sure what else you might mean by abstract/contain.
from curl.
Hey Toby,
Don't let John fool you, wire.js exists mostly because of him. So, technically speaking, he corrupted me ;)
If you need, in the short term, wire can be used in a limited way without AMD. The create
keyword can take a regular function or constructor. There isn't any real documentation on doing that, mostly because we don't use it that way, and I think there's only 1 user doing it right now.
Have a look at the non-AMD unit test for a very basic example. It uses the TestConstructor directly in a wire spec. So, maybe one option for you is to load wire itself via curl, but then use actual functions/constructors for libs that are using globals and can't be converted easily to AMD?
curl(['wire'], function(wire) {
wire({
// use actual functions/constructors with create
});
}
FWIW, technically, you can also load wire.js using a script tag if you really need that, but I wouldn't recommend it :) Most of the plugins can't be loaded via script tag, and that's where most of the good stuff is! Script tag support might go away in the future, too.
If you have wire.js questions, don't hesitate to ask!
from curl.
We're also investigating UMD-formatted modules (AMD + CJSM with node extensions), and old school name-spaced global objects. Thoughts?
from curl.
Yeah, sorry I haven't chimed in. I grabbed the dev version and am no longer experiencing the issue. Should have tried it myself, but so many repositories on here don't have a dev branch, so I forget to look.
UMD's goals seem to be limited to offering environment agnosticism. That's great, but the main issue I have (and many others have) is not being compatible with non-amd modules. And I still hate the path-centric nature of [_]MD. Again, on both counts, @jcoglan's approach is better, imo. However, he doesn't seem to offer much in the way of keeping objects out of the global space, but I feel that wouldn't be too much of a stretch.
from curl.
...Oh, and @briancavalier, thanks for the heads up! That's very helpful. I wonder if the plugins would work with @jcoglan's approach.
from curl.
No problem!
They may, but I haven't looked closely enough at his approach. Wire basically relies on an environment-provided loader, which, right now, can be either an AMD-provided local require, or Node's require. There might be ways to have wire accept a pluggable loader, but that could tie a wire spec to a particular loader if the module id syntax is different, e.g. dot separators versus slashes, or different ways of specifying a base url, etc. I guess that's not too bad, since if you change to a radically different loader, you're probably gonna be refactoring a lot more than the module ids in your wire specs.
I'll have to give it more thought--hard to say right now whether we want to go down the pluggable-loader road with wire or not.
from curl.
Related Issues (20)
- curl-css shouldn't wait for readystate == 'complete' HOT 7
- What if the module is a function? HOT 1
- Similar functionality of curl with require.js map config? HOT 1
- Using domReady! as a dependency argument causes an error HOT 4
- dealing with the window object HOT 7
- Unhandled error is eaten by curl when bootstrap code has a json plugin dependency HOT 5
- For anyone facing the error : Multiple anonymous defines encountered HOT 1
- Multiple bundles HOT 17
- Remove old IE event listeners in domReady HOT 1
- License for curl HOT 4
- "undefined" from import when define function throws an exception HOT 8
- Modules "undefined" when error occurs HOT 1
- "new Promise()" syntax non-standard? HOT 1
- Promise.then doesn't wait HOT 5
- Add build with js plugin
- multiple anonymous defines HOT 2
- How to help curl guess the right plugin? (e.g. json! for *.json) HOT 8
- Feature Request: Add syntax to bypass plugins
- cjsm11 loader hides a TypeError and falsely reports success
- ε¦δΉ HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from curl.