RequireJS, Circular Dependencies and Exports "Magic" Method
Asked Answered
E

1

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.

Eminent answered 28/1, 2015 at 13:23 Comment(2)
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.Isidraisidro
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.Eminent
I
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"]);
Isidraisidro answered 28/1, 2015 at 13:30 Comment(2)
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.Eminent
It seems as if the allegedly magic exports module doesn't do what it's said. See my editIsidraisidro

© 2022 - 2024 — McMap. All rights reserved.