【问题标题】:NodeJs Require module returns an empty objectNodeJs Require 模块返回一个空对象
【发布时间】:2019-02-23 12:34:12
【问题描述】:

我正在使用 NodeJS 8 LTS。

我有 3 个 js 脚本,其中:

// 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();
    }
};

当我运行 main.js 时,我得到了

(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.

调试,我发现在Factory.js中当它需要Domanis.js时const Domains = require('./Domains');它返回一个空对象。

在互联网上环顾四周,我发现当模块之间存在循环依赖关系时会发生这种情况(Require returns an empty object),但这里似乎并非如此。

有什么想法吗?

【问题讨论】:

  • 简而言之:当循环依赖发生时,Node 会创建空对象。然后,您必须通过动态获取依赖项或其他方式找到出路。此外,您可以使用名为 madge 的 npm 包检测循环依赖关系,使用 npx madge --circular &lt;app entry point&gt; 这是一个可以提供帮助的视频:youtube.com/watch?v=JQQX62cUaYw

标签: node.js


【解决方案1】:

最后,我得到了问题的根源。空对象是由于 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

因此,这会导致创建一个空对象的循环依赖

【讨论】:

  • 寻找循环依赖的一个好模块是 Medge。安装到您的开发依赖项并以 npx medge --circular &lt;EntryFile&gt; npmjs.com/package/madge 身份运行
【解决方案2】:

setImmediate 调用将延迟所需模块的加载,直到浏览器完成它需要做的事情。这可能会导致您在加载之前尝试使用此模块时出现一些问题,但您可以为此添加检查。

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

// produces the required object
let module;
setImmediate(() => {
  module = required('./someModule');
});

【讨论】:

  • 一切都错了(...浏览器,延迟)。至少你提供了 setImmediate 函数的线索,这在某些情况下可能会有所帮助。
猜你喜欢
  • 2014-07-15
  • 2021-02-14
  • 2016-06-04
  • 2015-10-22
  • 1970-01-01
  • 2020-05-12
  • 2017-02-28
  • 2017-02-26
  • 1970-01-01
相关资源
最近更新 更多