5

I'm using NodeJS 8 LTS.

I have 3 js scripts where:

// main.js
const dom = require ('./Domains/Domains');
const factory = require ('./Domains/Factory');
(async () => {
    const Domain = await factory.foo();  // <=== Error

})();

// Domains.js
class Domains {
    constructor (options = {}) {
        ....
    }
}
module.exports = Domains;

// Factory.js
const Domains = require('./Domains');
module.exports = {
   foo: async () =>{

      .... async stuff ...

     return new Domains();
    }
};

when I run main.js I get

(node:1816) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError: Domains is not a constructor
warning.js:18
(node:1816) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Debugging, I found that in Factory.js when it requires Domanis.js const Domains = require('./Domains'); it returns an empty object.

Looking around on internet I found that it happens when there are a circular dependencies between modules (Require returns an empty object) but It doesn't seem the case here.

Any idea?

Dan D.
  • 73,243
  • 15
  • 104
  • 123
Gappa
  • 757
  • 2
  • 16
  • 34
  • 1
    In short: Node creates empty objects when circular dependencies occurs. Then you have to find a way out by getting the dependency dynamically or something else. Also, you can detect circular dependencies with an npm package called **madge**, with `npx madge --circular ` Here's a video that could help: https://www.youtube.com/watch?v=JQQX62cUaYw – tkpb Feb 13 '22 at 11:51

2 Answers2

10

Finally, I got the the issue's origin. The empty object was due to a circular dependency derived by another require that was inside Domains.js

// Domains.js
const another_module= require("circular_dep_creator");
class Domains {
    constructor (options = {}) {
        ....
    }
}
module.exports = Domains;

// circular_dep_creator.js
const factory = require ('./Domains/Factory');
...
another stuff

So, this causes a circular dependency that creates an empty object

Gappa
  • 757
  • 2
  • 16
  • 34
  • 2
    A good module to find circular dependencies is Medge. Install to your Dev Dependencies and run as `npx medge --circular ` https://www.npmjs.com/package/madge – Lucas Fabre Feb 11 '20 at 20:26
-4

The setImmediate call will delay the loading of the required module until the browser has finished doing what it needs to do. This may cause some issues where you try to use this module before it is loaded, but you could add checks for that.

// produces an empty object
const module = require('./someModule');

// produces the required object
let module;
setImmediate(() => {
  module = required('./someModule');
});
Mykrosoft
  • 5
  • 1
  • 4
  • Everything wrong (...browser, delay). At least you give the clue for the `setImmediate` function that could help in some cases. – tkpb Feb 13 '22 at 11:58