2013-06-12 73 views
6

朋友已經問了一個有趣的問題,我試了幾件事情,但沒有用,有什麼辦法來重寫節點JS模塊?節點JS覆蓋標準模塊

例如,我想重寫readFile函數來使用S3存儲區而不是文件系統。 IE:

var fs = require('fs'); 

fs.readFile('my_text_file.txt', ...); 

實際運行這樣的事情

FileSystem.readFile = function() { 
    // Connect to S3 and retrieve remote file 
} 

我已經試過了原型,但似乎他們已經建立了本地模塊沒有__proto__對象,他們沒有一個.constructor屬性這對任何人都意味着什麼。

我想過使用Nodes VM,但這太嚴格了,因爲我希望用戶能夠通過npm安裝模塊並使用它們。

我其實是來創造一個新的模塊最近的(因爲我不能把一個名爲fs.js文件在我的文件夾node_modules,並要求它,它只是被忽略),只是硬設定的fs的值我想要什麼,但這不是很對,我希望用戶使用require('fs')並使用我的自定義功能。

這是否可能,而不編譯我自己的版本的節點JS?

+0

我還沒有使用node.js,所以這可能根本無法工作。你可以嘗試看看是什麼函數聲明'FileSystem',然後用它作爲你的自定義對象(「子類」它)的原型。 MyFS = {FileSystem.call(this);}; MyFs.prototype = new FileSystem();或者使用諸如goog.base和goog.inherit之類​​的東西來創建一個子類,該子類可以將其稱爲「父」函數並處理傳遞給構造函數的參數:http://docs.closure-library.googlecode.com/git/closure_goog_base。 js.html請注意,badse使用'arguments.callee.caller',它在ecma 5中不起作用,因此您必須重新編寫它。 – HMR

+0

關於goog.base和goog.inherits的好文章在這裏:http://bolinfest.com/essays/googbase.html – HMR

+0

爲了說明的目的,我製作了'FileSystem',模塊沒有'__proto__'對象,因此沒有構造函數。我得到的最接近的是直接設置對象的屬性,幷包括另一個腳本,但我想'require('fs')',它有我的自定義功能 –

回答

11

我覺得有責任強烈警告你不要覆蓋原生函數。話雖這麼說,這將工作:

main.js:

var fs = require('fs'), 
    oldReadFile = fs.readFile; 

fs.readFile = function (filename, options, callback) { 
    console.log('hey!'); 
    oldReadFile(filename, options, callback) 
}; 

var other = require('./other'); 
other.test(); 

other.js:

var fs = require('fs'); 

exports.test = function() { 
    fs.readFile('./main.js', {encoding: 'utf8'}, function (err, data) { 
    console.log(err, data); 
    }); 
}; 

你需要用自己的包裹你的用戶腳本首先覆蓋你想要什麼。

+0

+1用於警告。不要混淆基本模塊。 – aggsol

+0

我知道,我不會親自。至少沒有'vm',但這是一個有趣的問題。然而,這與我已經嘗試過的相同,並不是他想要的。 –

+0

@Laurent避免覆蓋原生函數的特定原因?我打算做一些類似的操作來覆蓋數據庫的讀寫操作。 – DanMatlin