【问题标题】:node.js: Accessing local variables from another modulenode.js:从另一个模块访问局部变量
【发布时间】:2012-12-10 19:22:52
【问题描述】:

我的问题

我正在编写一个名为anode 模块,其中require()s 是一个模块b(由陌生人编写)。不幸的是,a 不仅需要访问公共成员 - 它还需要访问在模块范围内声明的局部变量。

// a
var b = require('b');

console.log(b.public);
console.log(b.private); // undefined


// b
var c = require('c');
var stdin = process.stdin;

exports.public = true;
var private = true;

我的解决方案

// a
var b = require('b');
var srcPath = require.resolve('b');

console.log(b.public);
fs.readFile(srcPath, 'utf-8', function (err, src) {
    var box = {};
    var res = vm.runInNewContext(src, box, srcPath);
    console.log(box.private);
});

vm 不会将b 作为模块运行,因此无法从vm 的上下文中访问require() 等。所以有ReferenceErrors之类的:

    var res = vm.runInNewContext(src, box, scPath);
                 ^
ReferenceError: require is not defined
    at <module b>
    at <module a>
    at fs.readFile (fs.js:176:14)
    at Object.oncomplete (fs.js:297:15)

我的问题

获取在另一个模块中声明的局部变量的值最简洁的方法是什么?想法?

感谢您的帮助。

【问题讨论】:

  • 导出getter/setter?您肯定不希望其他人随意弄乱您所有的局部变量,对吗?
  • 编辑 b 以导出您要访问的数据。不要试图从外部侵入它。
  • 感谢您的想法。但是模块b 是由一个陌生人而不是我写的(我不想弄脏我的手)。 - 还有其他想法吗?
  • @fridojet,您找到解决方案了吗?
  • 我在 stackoverflow 上看到的最好的问题之一。这应该是一个节点模块。 +1

标签: javascript node.js serverside-javascript node-modules


【解决方案1】:

只需export 正确的值

模块 B

// b.js

// some local var
var foo = 'Bar';

exports.Foo = foo;
exports.Hello = 'World';

模块 A

// a .js
b = require('./b');
console.log(b.Foo); //=> 'Bar'
console.log(b.Hello); // => 'World'

在此处阅读有关nodejs module.exports 的更多信息

【讨论】:

  • I'm writing a node module called a, which require()s a module b (written by a stranger). - 这意味着:b 不是我写的(我不想弄脏我的手)。
  • 如果所有陌生人都能正确编写他们的模块,那就太好了。但事实并非如此。有时,你需要帮助他们导出他们应该做的事情。
【解决方案2】:

您可能永远不必这样做,但可能是有原因的。

您可以挂钩加载程序并注入 javascript 代码以导出您想要的内容。

// let's say you have node_modules/foreignmodule/index.js
// and in that script there is a local (not-exported) function foreignfunction().

var path = require('path');
_oldLoader = require.extensions['.js'];
require.extensions['.js'] = function(mod, filename) {
    if (filename == path.resolve(path.dirname(module.filename), 'node_modules/foreignmodule/index.js')) {
        var content = require('fs').readFileSync(filename, 'utf8');
        content += "module.exports.foreignfunction=foreignfunction;\n";
        mod._compile(content, filename);
    } else {
        _oldLoader(mod, filename);
    }
};

require('foreignmodule').foreignfunction();

【讨论】:

    【解决方案3】:

    查看我的模块import-locals

    const patcher = new Patcher();
    patcher.export("yourmodule", "Foo");
    const { Foo } = require("yourmodule");
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-05-15
      • 1970-01-01
      • 2017-04-23
      • 2020-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多