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,聲明已通過濾了全部已知攻擊。