[筆記] nodeJS VM module使用方法

[![](http://4.bp.blogspot.com/-cYYH7p934eo/ThtOFdAhz9I/AAAAAAAAMvc/CQiw0MV1lpc/s320/nodejs.png)](http://4.bp.blogspot.com/-cYYH7p934eo/ThtOFdAhz9I/AAAAAAAAMvc/CQiw0MV1lpc/s1600/nodejs.png)
在[node ](http://clonn.blogspot.com/2011/06/nodejscomet.html)裡面通常比較少寫到怎麼使用[vm module](http://nodejs.org/docs/v0.4.12/api/vm.html),今天看了這則[require() files that do not use module structure](http://groups.google.com/group/nodejs/browse_thread/thread/c45c7174baa0aab5),才曉得原來[vm 可以這樣子使用](http://clonn.blogspot.com/2011/09/nodejs-vm-module.html)。可以參考一下[source code](https://github.com/baudehlo/Haraka/blob/master/plugins.js) ,裡面的程式就是實際vm 運作的方式。 **時機** **官方解說** `JavaScript code can be compiled and run immediately or compiled, saved, and run later.

` 當我們需要執行一段程式 ,但是又不想寫成module 的模式(使用require),這個時候可以採取vm 來執行片段程式,簡單來說可以達到兩個目的: 1. **部份程式片段抽離。** 2. **不使用全域變數污染環境。** []() example.js `var vm = require('vm');



globalVar = 0;



var script = vm.createScript('globalVar += 1', 'myfile.vm');



for (var i = 0; i < 1000 ; i += 1) {

script.runInThisContext();

}



console.log(globalVar);

` 程式碼產生之後,使用runInThisContext,重複執行1000次之前產生的程式,實際得到的結果為:
[![](http://4.bp.blogspot.com/-Sx8CBcwEEes/TnnLHDgm4GI/AAAAAAAAN6w/nlNnqf9GJIU/s640/20110921_1.jpg)](http://4.bp.blogspot.com/-Sx8CBcwEEes/TnnLHDgm4GI/AAAAAAAAN6w/nlNnqf9GJIU/s1600/20110921_1.jpg)
範例中得知,其實vm 的執行方式類似於javascript eval,雖然前端是不喜歡這種eval (evil)作法,不過對於後端來說,似乎是一種將程式分離的方法之一。 **進階** 如果想要從外部寫檔案,又不想要使用require,那該怎麼做呢?比較好得選擇可以採取[file system](http://nodejs.org/docs/v0.4.12/api/fs.html#file_System),直接將檔案讀取回來之後,再使用一個參數下去接收,比較理想的function 在範例裡面來看,推薦使用[vm.runInNewContext()](http://nodejs.org/docs/v0.4.12/api/vm.html#vm.runInNewContext),實際來個範例。 testVm.js,要抽離的javascript `count += 200;

k += 100;

` vm.js `var vm = require('vm'),

fs = require('fs'),

sandbox = {

id : '123',

count : 0,

k : 0

},

jsCode;



jsCode = fs.readFileSync('./testVm.js');



vm.runInNewContext(jsCode, sandbox, 'myfile.vm');



console.dir(sandbox);

` 實際結果
[![](http://4.bp.blogspot.com/-r1JDj6vb2uA/TnnZ00QuNfI/AAAAAAAAN60/oRGgb-LFurE/s640/20110921_2.jpg)](http://4.bp.blogspot.com/-r1JDj6vb2uA/TnnZ00QuNfI/AAAAAAAAN60/oRGgb-LFurE/s1600/20110921_2.jpg)
將需要的變數全部包裝於sanbox,讀取程式之後,參數會存回sanbox中,就可以不用使用全域變數(Global variable),如此可以達到將**程式抽離,變數封裝**。 **結語** 之前還真沒有碰過[vm](http://clonn.blogspot.com/2011/09/nodejs-vm-module.html),只知道node 裡面有這個模組,實際到底要怎麼使用卻不太清楚,經過討論串提出之後,配合著實例重新閱讀API,就可以明白到底VM的產生是為了什麼,要怎麼去使用這個模組,也許大家會有更好得用法,歡迎提出! **[工商服務]** nodeJS 華文資料需要**你**的支持,希望能夠聽到你的回應及分享,歡迎加入。
- [NodeJS Wiki](http://wiki.nodejs.tw/) - [NodeJS Taiwan 粉絲頁](http://www.facebook.com/NodeJS.tw) - [NodeJS Taiwan 社團](http://www.facebook.com/groups/node.js.tw/)

CaesarChi

Web developer, focus on website fullstack, special JavaScript, and love sharing developing experience and communicate with developers. http://about.me/clonn