Reputation: 2846
I have following module configuration:
Global -> Collections -> Favorites
(global requires collections, collections require favorites).
At the same time Favorites
also need Global
module (for its' other properties).
Sample code:
define("global", ["collections"], function(Collections) {
console.log("Defining global");
var Global = {
env: "home",
collections: Collections
};
return Global;
});
define("collections", ["favorites"], function(Favorites) {
console.log("Defining collections");
var collections = {
likes: function() {},
favorites: Favorites
};
return collections;
});
define("favorites", ["global"], function(Global) {
console.log("Defining favorites");
var Favorites = function(name) {
console.log(Global.env)
this.name = name;
};
return Favorites;
});
require(["global"], function(Global) {
console.log("global", Global);
console.log("collections", Global.collections);
console.log("favorites", Global.collections.favorites);
var Favorites = Global.collections.favorites;
Favorites();
});
I've also created jsfiddle for this case: http://jsfiddle.net/NBSzC/
As you can see this codes produces error as we are trying to read value (env
) from undefined
.
Here on StackOverflow there is other helpful ticket on the same case: How to handle circular dependencies with RequireJS/AMD?
Using it I was able to make it "work", please check following fiddle: http://jsfiddle.net/NBSzC/1/
And the issue here is in the fact that I had to use
console.log(Global.Global.env)
as original Global now points to exports object and there we've set up link to Global as Global.
We could also do following in the Global module but I believe this is another hack:
_.extend( exports, Global );
In the corresponding link there was no such problem at all, not sure what I am doing wrong.
Upvotes: 2
Views: 902
Reputation: 40318
I have the feeling that circular dependencies are a "smell" that the code organization suffers.
In your case I would argue that you do not need the collections
field in globals. If something depends on collections, why not ask for the collections module directly?
In this case the dependencies will be: Collections → Favorites → Globals (but Globals does not point back to Favorites, thus the circle is broken).
Then, if you really need to load everything from the beginning, you could modify the require()
call:
require(["global","collections"], function(Global,Collections) { ...
Or define a bootstrap module that requires everything and require that:
define("bootstrap",["global","collections","favorites"], function(...) { ...
require("bootstrap", ...)
Of course I do not have all the details of your project, so the solution may be different. But still the main point is that circular dependencies are a smell.
Upvotes: 1