【问题标题】:Why so strange behaviour when using "require" in NodeJS?为什么在 NodeJS 中使用“require”时会出现如此奇怪的行为?
【发布时间】:2019-12-23 14:29:18
【问题描述】:

当我在ClassB中导入ClassA,然后在ClassB中导入ClassA,导入的ClassA是一个空Object。为了演示,我有这 3 个文件:

ClassA.js

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

class ClassA {
    static test() {
        ClassB.test();
    }
}

module.exports = ClassA;

ClassB.js

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

class ClassB {
    static test() {
        console.log('ClassA.test', ClassA.test);
    }
}

module.exports = ClassB;

index.js

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

ClassA.test();

当我运行node index.js 时,我希望在控制台中看到ClassA.test function,但它却输出ClassA.test undefined。是一些未记录的东西,还是一个错误?

【问题讨论】:

    标签: node.js


    【解决方案1】:

    你有一个循环依赖。解决方案是拥有一个需要两者的第三类,并使用来自ClassAClassB 的任何代码,反之亦然。

    const ClassA = require('./ClassA');
    const ClassB = require('./ClassB');
    
    class ClassC {
        static test() {
            ClassA.test();
            ClassB.test();
        }
    }
    

    当我运行 node index.js 时,我希望看到 ClassA.test 函数 控制台,但它输出 ClassA.test undefined 代替。是不是有些 未记录的东西,或者它是一个错误?

    不,这不是错误,也不是未记录的。

    你可以在这里阅读更多关于它是如何处理的:https://nodejs.org/api/modules.html#modules_cycles


    您也可以进行延迟加载,并针对这种特殊情况解决您的问题。但在大多数情况下,循环引用是代码编写不佳的症状。

    class ClassB {
        static test() {
            const ClassA = require('./ClassA')
            console.log('ClassA.test', ClassA.test);
        }
    }
    
    module.exports = ClassB;
    

    【讨论】:

    • 是的,在 test() 方法中使用 const ClassA = require('./ClassA') — 这正是我前段时间修复它的方式。只是感兴趣,为什么会这样。
    • 是的,当您第一次遇到错误时会有点困惑,但它是有道理的 :)。很高兴能提供帮助。
    • 我刚刚意识到为什么我要问它是否没有记录或者它是一个错误:NodeJS 通常非常慷慨地显示警告/错误,但是当循环依赖发生时它会保持沉默。它只是提供了一个损坏的对象,而没有说任何有点意外的行为。
    • 我同意这一点,警告肯定是积极的。
    【解决方案2】:

    你有一个循环依赖,所以 Node 不能确定哪个模块的顶级代码应该首先运行 - 一个模块需要首先运行它的顶级代码,这样应该导出一些东西,以便其他模块可以通过require 导入它。但是如果两者都依赖于另一个,那么第一个运行的将有其require 调用另一个解析为undefined

    最好的解决方案是重构它以避免循环依赖。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-21
      相关资源
      最近更新 更多