将节点模块变量注入范围

Inject node module variable to scope

是否可以使用节点模块实现此行为?

module.js:

module.exports = function () {
    var test.fn = function () {
        console.log("$test.fn()");
    }

    var test.fn2 = function () {
        console.log("$test.fn2()");
    }

    var variable = "test";
};

app.js:

require("./module.js")();

test.fn();
test.fn2();
otherFunction(variable);

我不想做这样的事$ = require("./module.js")(); $.test.fn(); 我想在没有包装变量的情况下将此变量注入 app.js 范围。

编辑:

我最终使用了这个:

module.js:

module.exports = function () {
    eval(String(inject));

    var inject = (
        this.$module1 = {},
        this.$module1.fn = function () {
            console.log("$module1.fn()");
        }
        );
};

app.js:

require("./module.js")();

$module1.fn();

模块中的顶级作用域实际上是一个函数作用域(node.js 加载器将每个模块包装在一个函数中,然后调用该函数来执行模块中的代码)。因此,没有公开可用的 "root" 对象,我们可以通过编程方式为其分配属性。

因此,这意味着如果不在相当大的 hack 中使用 eval(),就不可能在模块中以编程方式在模块范围的顶层添加新变量。函数作用域在 Javascript.

中不能那样工作

您也可以让模块将事物分配给 global 对象,在这些对象中它们可以在没有前缀的情况下使用,但这绝不是推荐的做法。 node.js 模块的全部要点是避免使用任何全局变量并使代码完全自包含,几乎没有全局冲突的可能性。

或者,您可以让您的模块导出一个巨大的 Javascript 字符串,然后 eval() 它在 app.js 内部,以便在模块范围内定义新变量。再次 - 不推荐。

你最好的办法就是做 "node.js way" 的事情,把所有东西都放在一个对象上,然后导出那个对象。这是一种变体:

app.js

var test = require("./module.js")();

test.fn();                  // "executing fn"
test.fn2();                 // "executing fn2"
console.log(test.myVar);    // "test"

module.js

module.exports = function () {
    return {
       fn: function () {
           console.log("executing fn");
       },
       fn2: function() {
            console.loog("executing fn2");
       },
       myVar: "test"
    }
};

这个答案不应该鼓励您在 node.js 模块中使用 global(请参阅上面 jfriend00 的评论),因为它会使您的代码容易与其他模块发生名称冲突,并且因此你的模块不那么便携。

在 module.js 中,您可以访问 node.js 运行时环境的 global 对象。

module.js:

global.test = {
    fn: function() {
        //Do something
    },
    fn2: function() {
        //Do something different
    },
    variable: "test variable"
}

app.js

require("./module.js"); //just include, no need for a wrapper variable
test.fn();
test.fn2();
console.log(test.variable);

请注意,如果全局变量 test 已经存在,此技术将覆盖它。

您可以使用 IIFE 做类似的事情。该方法在需要时会自动 运行 和 return 一个对象,然后您可以在您的应用程序中使用该对象。

module.js:

global.test = (function() {
  return {
    fn: function() {
      console.log("executing fn");
    },
    fn2: function() {
      console.log("executing fn2");
    },
    variable: "test"
  }
})();

app.js

require("./module.js"); //just include, no need for a wrapper variable
test.fn();
test.fn2();
console.log(test.variable);

请注意,如果全局变量 test 已经存在,此技术将覆盖它。