4

考虑以下代码:

vm = require('vm');
context = vm.createContext({});
vm.runInContext("Buffer.from('abc').toString()", context);

ReferenceError: Buffer is not defined请注意,由于 Buffer 是 Node.js 已添加为Node Specific Global Object的特定于 Node.js 的构造,因此这会产生。 (请注意,其他 JS 全局变量喜欢Math并且Array不共享此问题。) 可以通过将上述代码修改为来解决此特定问题

vm = require('vm');
context = vm.createContext({Buffer});
vm.runInContext("Buffer.from('abc').toString()", context);

但是,如果我希望导入每个特定于节点的全局全局变量,那么似乎我必须一一列出它们。鉴于 Node.js 相对频繁地添加全局对象,有没有办法可以将所有 Node.JS 的全局对象传递给 vm 上下文?或者,是否有一种编程方式来构建所有 Node Globals 的列表?

注意:global不同节点版本的使用不一致:例如Buffer适用于global节点 v8 和 v10,但不适用于 v12。

4

2 回答 2

0

我懂了。


const cloneGlobal = () => Object.defineProperties(
    {...global},
    Object.getOwnPropertyDescriptors(global)
)

测试:

> const nG = cloneGlobal()
> nG.myVar = 'a';
'a'
> myVar
Uncaught ReferenceError: myVar is not defined
> 'myVar' in global
false
> 'myVar' in nG
true
> 'Buffer' in nG
true

编辑:为作者的示例添加示例代码:

vm = require('vm');

const cloneGlobal = () => Object.defineProperties(
    {...global},
    Object.getOwnPropertyDescriptors(global)
)

context = vm.createContext(cloneGlobal());
const ret = vm.runInContext("Buffer.from('abc').toString()", context);

console.log(ret); // abc
于 2021-11-10T22:48:17.400 回答
0

使用“vm”模块的全部原因是将正在运行的程序的上下文与正在执行的代码隔离开来。

如果你想在当前上下文中执行任意 JavaScript,你可以使用eval. 没有理由使用 vm.createContext。

eval("Buffer.from('abc').toString()");
于 2021-11-11T01:37:46.843 回答