下面的代码使用本机节点vm
库,它允许您在不同的上下文中评估javascript字符串。
example.js
中的特定代码是一个javascript字符串,它向.marker
全局变量添加值为true
的属性Array
,然后需要一个文件{{1 (见下文),然后记录global.js
。以下代码记录Array.marker
。
true
以下是var vm = require('vm')
var code = [
'Array.marker = true',
"require('./global.js')",
'console.log(Array.marker)', // => true
].join('\n')
var script = new vm.Script(code, { filename: 'example.js' })
script.runInNewContext({
'require': require,
'console': console
})
的内容,这是一个简单的模块,可将global.js
的值更改为Array.marker
。
false
这里应该发生的是var hi = function () {
Array.marker = false
}
module.exports = hi()
中的代码应该设置vm
到Array.marker
,然后true
模块应该将值更改为{{ 1}}它应该记录global.js
。
如果您继续运行false
之外的javascript字符串的内容,在其自己的文件中,您将获得预期结果,false
将等于vm
。
Array.marker
问题是:为什么false
没有更新到正确的值(Array.marker = true
require('./global.js')
console.log(Array.marker) // => false
)? 我如何允许{{1}的值从Array.marker
模块中获取更新?
这是本机node.js true
模块的问题吗?或者这不应该是可能的吗?或者我的设置关闭了吗?
更新
我认为这个错误更深一些。它更多地与导入的Array.marker
的行为有关,然后与global.js
的行为有关,以更准确地证明。
在这里,我从新的vm上下文中更改vm
的值,您可以看到它在vm运行后对全局require
没有影响。这是预期的行为,因为我没有将任何内容传递给vm
。
Array.marker
然而,当我将Array.marker
带入vm
时会发生非常意外的事情。所需的代码维护父上下文的范围。因此,使用给定的代码,您将获得意外的结果。由于需要调用,vm脚本var vm = require('vm')
var code = [
'Array.marker = true',
].join('\n')
vm.runInNewContext(code)
console.log(Array.marker) // => undefined [expected]
中的全局不会更改,您可以通过设置require
来查看require调用正在编辑父范围。
vm
真正的问题是如何在Array.marker
内实例化Array.marker
的新实例,而不是导入父类?保持本地化为var vm = require('vm')
var code = [
'Array.marker = true',
"require(\'./global.js\')",
'console.log(Array.marker)' // => true [unexpected]
].join('\n')
vm.runInNewContext(code, {
require: require,
console: console
})
console.log(Array.marker) // => false [unexpected]
,而不是让它泄漏到父级。
答案 0 :(得分:0)
这样的事情会起作用吗?
var gbl = require('./global.js');
scriptText = "Array.marker = true; gbl(Array.marker);"
var context = vm.createContext();
var script = vm.createScript(scriptText);
var fn = script.runInContext(context);
fn(gbl);
您需要更改global.js中的函数,以接受Array.marker作为参数。