0

Hello I'm looking fo efficient way to split node js into couple of separate modules for better management and I came across a problem what i cant overcome. I will explain on example code:

server.js

const module1 = require('./lib/module1');
const module2 = require('./lib/module2');

module1.example();

/lib/module1.js

const module2 = require('./module2');

class Module1 {
    constructor() {}

    example() {
        var test = module2.someNumber();
        console.log(test);
    }

    getNumber() {
        var number = 10;
        return number;
    }
}
module.exports = new Module1();

/lib/module2.js

const module1 = require('./module1');

class Module2 {
    constructor() {}

    someNumber() {
        let some = module1.getNumber();
        return some;
    }
}
module.exports = new Module2();

So im calling module1.example(); and I'm getting error:

module1.getNumber is not a function

I know that it is because both modules request each other and but there is some solution for that?

falinsky
  • 7,229
  • 3
  • 32
  • 56
R3ason
  • 86
  • 1
  • 2
  • 8
  • 2
    This looks like an [XY problem](http://xyproblem.info/). It's impossible to tell what the real problem is because you're stripped any sign of what it is out. In general: Restructure your code so you don't have mutually dependant modules. – Quentin Aug 30 '18 at 12:49

2 Answers2

0

To cope with such a cyclic dependencies you can just require needed modules only where they are needed:

module1.js

class Module1 {
  constructor() {}

  example() {
    const module2 = require('./module2');

    var test = module2.someNumber();
    console.log(test);
  }

  getNumber() {
    var number = 10;
    return number;
  }
}
module.exports = new Module1();

module2.js

class Module2 {
  constructor() {}

  someNumber() {
    const module1 = require('./module1');

    let some = module1.getNumber();
    return some;
  }
}
module.exports = new Module2();

But in general it's better to try eliminate such a cyclic dependencies.

falinsky
  • 7,229
  • 3
  • 32
  • 56
0

There are a couple of tricks to deal with circular dependencies in node, one method is mentioned in the other answer and involves resolving dependencies locally.

Another solution is to move the require down, make it the very last line of the module that uses another module:

module1.js

class Module1 {
    constructor() {}

    example() {
        var test = module2.someNumber();
        console.log(test);
    }

    getNumber() {
        var number = 10;
        return number;
    }
}
module.exports = new Module1();

const module2 = require('./module2');

module2.js

class Module2 {
    constructor() {}

    someNumber() {
        let some = module1.getNumber();
        return some;
    }
}
module.exports = new Module2();

const module1 = require('./module1');

This way the module resolver doesn't try to first load the module (and get the empty export upon hitting the cycle) but instead resolving is postponed until the actual code is executed (and at that moment, dependencies are already there).

Wiktor Zychla
  • 47,367
  • 6
  • 74
  • 106
  • I like your answer but tell me should im using it or try to avoid circular dependency and use it only if there is no other way to avoid. – R3ason Aug 30 '18 at 13:04
  • There is no clear answer but a recommendation only. The recommendation is to **avoid** circular dependencies as chances are you could get into even more trouble soon. However, it's a recommendation only so not following it makes you are on your own. – Wiktor Zychla Aug 30 '18 at 13:06