8

Basically, the idea is that "sub" module creates an object, and that object should be part of a utilities library which is the "main" module. However, the "sub" object depends on utilities from "main":

// Main module
define(['sub'], function(sub) {
    var utils = {
        utilityMain: function () {
           // ...
        };
        // ...
    };

    tools.subModule = sub;

    return tools;
});

// Sub module
define(['main'], function(main) {
    return new (function () {

        // Singleton object using functions in main module
        var somestuff = function () {
            main.utilityMain();
            // etc
        };
    })();
});   

How can I achieve this with require.js without creating a black hole that would swallow the whole planet?

Thank you very much.

1 Answer 1

6

There are a few things suggested in the docs:

b can fetch a later after modules have been defined by using the require() method (be sure to specify require as a dependency so the right context is used to look up a)

e.g.:

// Sub module
define(['require'], function(require) {
    return new (function () {

        // Singleton object using functions in main module
        var somestuff = function () {
            require('main').utilityMain();
            // etc
        };
    })();
});

or

you could instead use exports to create an empty object for the module that is available immediately for reference by other modules

e.g.:

// Main module
define(['sub', 'exports'], function(sub, exports) {
    exports.utilityMain: function () {
       // ...
    };

    exports.subModule = sub.sub;
});
// Sub module
define(['main', 'exports'], function(main, exports) {
    exports.sub = new (function () {

        // Singleton object using functions in main module
        var somestuff = function () {
            main.utilityMain();
            // etc
        };
    })();
});

and

Circular dependencies are rare, and usually a sign that you might want to rethink the design

Sign up to request clarification or add additional context in comments.

6 Comments

"rethink the design", I totally agree but it's a bit tight for that at the moment. I have already researched and looked into what you're proposing... I've been trying to wrap my head around the exports object for the past two days, and now you're telling me it is available immediately? I thought that exports is returned to define/require only once the factory function resumes execution? On a second look, it seems you're suggesting that main should resume execution only once sub resumes?
I would really appreciate it if you could really lay out the order in which these things all happen. I think this is where I fail to grasp how this workaround solves my problem. Thanks!
Using exports just allows each module to have a reference to some object instead of undefined for each module. You can't immediately use the functions of either module, but you can be sure that the references will be set up properly at runtime. Think of both module definitions running in parallel. They both know where to look for the other module, but neither can interact until they're both complete.
I understand, but I don't see how that solves it. Because the sub model explicitly depends on some functions in main, but main only needs to get the return value from sub. I think I will just load them both in a parent module and have that one combine and return them as a single object. Talk about "rethinking the design"... :) Of course if you feel like elaborating further on your solution I am indeed all ears!
What's your definition of solve? The exports technique solves the problem where circularly-dependent modules will return undefined. The require technique solves the problem of having a dependency loop at define-time.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.