当我在同一目录或父目录中时,为什么“要求”的行为有所不同?

时间:2019-05-21 16:11:13

标签: javascript node.js

在测试某些代码时,遇到了无法解释的情况。经过数小时的谷歌搜索,我真的无法找出正确的问题要问。在正确的方向或正确的术语上的任何帮助将不胜感激..!

因此,..当我需要位于同一工作目录中的文件时,我可以执行以下操作:

const { ports, keys } = require('./activeConfig');
console.log(ports, keys, activeConfig);

在这种情况下,ports, keys,activeConfig都已定义,我可以像完成操作一样使用该模块:

const { ports, keys } = require('./activeConfig');
const activeConfig = require('./activeConfig');
console.log(ports, keys, activeConfig);

但是,如果我尝试从外部目录执行完全相同的操作,则像这样:

const { ports, keys } = require('../../config/activeConfig');

const { ports, keys } = require('./config/activeConfig');

activeConfig不再定义,并且出现错误。

为什么这种行为因我要导入的位置而异?还是这与我导出模块的方式有关?
我希望代码保持整洁,因此我希望避免编写第二个require。可能有一种不同的方法可以一齐完成所有这些工作吗?

我想要的模块是具有休假代码的Singleton:

const database = {...}
const keys = {...}
const ports = {...}
const tokens = {...}

module.exports = activeConfig = (() => {
    let _database = database;
    let _keys = keys;
    let _ports = ports;
    let _tokens = tokens;

    return {
        setDatabase: (value) => {
            if (value) {...}
            return activeConfig;
        },
        setKeys: (value) => {
            if (value) {...}
            return activeConfig;
        },
        setPorts: (value) => {
            if (value) {...}
            return activeConfig;
        },
        setTokens: (value) => {
            if (value) {...}
            return activeConfig;
        },
        updateConfig: () => {
               ...
            return activeConfig;
        },
        get database() {
            return _database;
        },
        get keys() {
            return _keys;
        },
        get ports() {
            return _ports;
        },
        get tokens() {
            return _tokens;
        },
        set database(value) {...},
        set keys(value) {...},
        set ports(value) {...},
        set tokens(value) {...}
    };
})();

1 个答案:

答案 0 :(得分:2)

正在发生的事情是您的activeConfig模块正在声明一个隐式全局变量。

该行:

module.exports = activeConfig = (() => { //...

这将在您第一次需要模块时将变量activeConfig泄漏到全局范围。

然后,当您在其他地方再次需要该模块时,NodeJS只会拉出先前导出的对象form the cache,并且不会执行分配。

尝试在严格模式下运行代码,在"use strict"顶部添加activeConfig.js,您会发现它不会泄漏全局变量。

泄漏全局变量是不好的,我建议您在导出的对象中放置对同一实例的引用,以便在需要时可以将其“分解”。

例如:

"use strict"
module.exports = (() => {
    // ....
    return {
       // ....
        get instance() {
            return this;
        },
    };
})();

然后在您需要时:

const { ports, keys, instance: activeConfig } = require('./config/activeConfig');