vm是node的一个核心模块,核心功能官方文档介绍是:javascript
The vm module provides APIs for compiling and running code within V8 Virtual Machine contexts. The vm module is not a security mechanism. Do not use it to run untrusted code. The term "sandbox" is used throughout these docs simply to refer to a separate context, and does not confer any security guarantees.
意思就是:vm能够使用v8的Virtual Machine contexts动态地编译和执行代码,而代码的执行上下文是与当前进程隔离的,可是这里的隔离并非绝对的安全,不彻底等同浏览器的沙箱环境。html
vm的使用很简单,下面是几个例子:vue
vm.runInNewContextjava
const vm = require('vm'); const sandbox = { a: 1 }; // 在新的上下文运行 const result = vm.runInNewContext('a += 1', sandbox); console.log(result);// 2 console.log(sandbox);// { a: 2 }
vm.runInContextnode
const vm = require('vm'); const sandbox = { a: 1 }; // https://nodejs.org/api/vm.html#vm_what_does_it_mean_to_contextify_an_object vm.createContext(sandbox); // 在执行上下文运行 const result = vm.runInContext('a += 1', sandbox); console.log(result);// 2 console.log(sandbox);// { a: 2 }
vm.runInThisContextgit
const vm = require('vm'); global.a = 1; // 在当前上下文运行 vm.runInThisContext('a += 1'); console.log(global.a);// 2
我我的理解vm的使用场景有2个:github
由于node的js代码是单线程,在并发的场景下,须要考虑上下文的竞争和互相影响,直接使用vm,能够最小成本的解决这个问题。api
vue ssr在2.3.0之前,就是用vm来作隔离的渲染的,可是也带来了性能的问题,具体能够查看文档的介绍。浏览器
这在某些需求场景下只能使用vm。安全
vm也有明显的劣势:
这里有文章比较eval
和vm
的性能:https://odino.org/eval-no-more-understanding-vm-vm2-nodejs/。(固然eval的安全问题更大,这是另外的话题)。
vm也存在安全问题,对于执行外部的代码,可能引起安全问题。
因此有个开源库专门解决了这个问题,https://github.com/patriksimek/vm2,声明已通过滤了全部已知攻击。