在vm脚本上下文中传递函数
比方说,我有一个库模块,看起来像这样:
module.exports = { increment: function() { count++; } }
我想在一个dynamic生成的脚本中使用它,如下所示:
(function() { lib.increment(); })();
通过在沙箱中传递:
var sandbox = { count: 1 lib: require('./lib') } var script = new vm.Script('(function() { lib.increment() })();'); script.runInNewContext(sandbox);
我碰到的明显问题是我一方面不能要求“lib”,因为“count”没有在lib.js中定义; 另一方面,如果我在“lib.js”文件的输出上面定义了var count
,那么这个新的count
variables将会受到影响,而不是在沙盒中。
以下是我想尊重的约束条件:
- 在生成的文件上使用vm而不是eval()和require()
- 在外部文件中定义“lib”
- 没有修改自动生成的脚本,所以没有使用
lib.increment.apply(context)
或类似的东西
到目前为止,我发现的唯一解决scheme是将生成的脚本中的lib
函数预先作为string预先定义,或者直接在sandbox
对象上定义它们,我发现这是不太理想的select。
在require
调用中似乎没有任何方法传递variables的上下文。
实现这一点的一种方法是让你的lib
模块是一个接受上下文的函数,然后返回正确的接口。
lib.js
module.exports = function(context) { var count = context.count; return { increment: function() { count++; } }; };
main.js
var sandbox = { count: 1 }; sandbox.lib = require('./lib')(sandbox); var script = new vm.Script('(function() { lib.increment() })();'); script.runInNewContext(sandbox);