2011年9月21日 星期三

[筆記] nodeJS VM module使用方法


node 裡面通常比較少寫到怎麼使用vm module,今天看了這則require() files that do not use module structure,才曉得原來vm 可以這樣子使用。可以參考一下source code ,裡面的程式就是實際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次之前產生的程式,實際得到的結果為:



範例中得知,其實vm 的執行方式類似於javascript eval,雖然前端是不喜歡這種eval (evil)作法,不過對於後端來說,似乎是一種將程式分離的方法之一。

進階
如果想要從外部寫檔案,又不想要使用require,那該怎麼做呢?比較好得選擇可以採取file system,直接將檔案讀取回來之後,再使用一個參數下去接收,比較理想的function 在範例裡面來看,推薦使用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);

實際結果

將需要的變數全部包裝於sanbox,讀取程式之後,參數會存回sanbox中,就可以不用使用全域變數(Global variable),如此可以達到將程式抽離,變數封裝

結語
之前還真沒有碰過vm,只知道node 裡面有這個模組,實際到底要怎麼使用卻不太清楚,經過討論串提出之後,配合著實例重新閱讀API,就可以明白到底VM的產生是為了什麼,要怎麼去使用這個模組,也許大家會有更好得用法,歡迎提出!

[工商服務]
nodeJS 華文資料需要的支持,希望能夠聽到你的回應及分享,歡迎加入。

沒有留言:

張貼留言

Facebook