0

I've been trying to get RequireJS set up to handle circular dependencies using the special 'exports' magic module as recommended by James Burke's answer to this question.

Following the example given by @jrburke in that question:

define("Employee", ["exports", "Company"], function(Company) {
    function Employee(name) {
        this.name = name;
        this.company = new Company.Company(name + "'s own company");
    };
    exports.Employee = Employee;
});
define("Company", ["exports", "Employee"], function(Employee) {
    function Company(name) {
        this.name = name;
        this.employees = [];
    };
    Company.prototype.addEmployee = function(name) {
        var employee = new Employee.Employee(name);
        this.employees.push(employee);
        employee.company = this;
    };
    exports.Company = Company;
});

jsfiddle

The problem is that using his own example, the exports module is undefined, and therefore exports.Employee and exports.Company don't set. If I try to include exports as an argument of the define callback functions, it simply initializes in both cases as empty and does not carry the constructor functions it was assigned.

What am I doing wrong?

EDIT: Through trial and error, I got the above code working at: http://jsfiddle.net/jpk45vow/4/. Can anyone explain why it works, because it makes no sense to me.

Community
  • 1
  • 1
Michael.Lumley
  • 2,345
  • 2
  • 31
  • 53
  • it seems as if the exports module wasn't a global object. It has a local scope as a helper to export your modules. That's why it's empty in main. In fact, you don't need to require it nor use it in your main module. – ffflabs Jan 28 '15 at 14:12
  • Yes, after reading your comments, it seems to me that what the magic module is doing is creating a container object very similar to the one you developed below, except each module has it's own container. Then when main requires the module, requireJS returns the container instead of the module, resolving all of the dependency problems. – Michael.Lumley Jan 28 '15 at 14:15

1 Answers1

3

Edit: I couldn't find more info about the magic exports method. I could, however, mimic its intended behavior with a dummy "Container" module. See it in this fiddle: http://jsfiddle.net/amenadiel/a7thxz98/

console.log("start");

define("Container",function() {
    var Container={};
    return Container;
});


define("Employee", ["Container"], function(Container) {
    var Employee= function(name) {
        this.name = name;
        this.company = new Container.Company(name + "'s own company");
    };
    Container.Employee = Employee;
});

define("Company", ["Container"], function(Container) {
    var Company=function(name) {
        this.name = name;
        this.employees = [];
    };
    Company.prototype.addEmployee = function(name) {
        var employee = new Container.Employee(name);
        this.employees.push(employee);
        employee.company = this;
    };
    Container.Company = Company;
});

define("main", ["Container","Employee","Company" ], function ( Container) {
    var john = new Container.Employee("John");
    var bigCorp = new Container.Company("Big Corp");
    bigCorp.addEmployee("Mary");
    console.log(bigCorp);
});

require(["main"]);
ffflabs
  • 17,166
  • 5
  • 51
  • 77
  • Yes, as I said, when I try that the `exports` object initializes as empty and does not carry the constructor functions it has been assigned. – Michael.Lumley Jan 28 '15 at 13:31
  • It seems as if the allegedly magic exports module doesn't do what it's said. See my edit – ffflabs Jan 28 '15 at 14:01