2013-06-12 18 views
6

L'amico ha posto una domanda interessante e ho provato alcune cose, ma inutilmente, c'è un modo per sovrascrivere un modulo Node JS?Node JS sovrascrive il modulo standard

Per esempio, voglio sovrascrivere la funzione readFile per usare un bucket S3 invece del filesystem. IE:

var fs = require('fs'); 

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

corre in realtà qualcosa di simile

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

Ho provato il prototipo, ma sembra che hai impostato moduli nativi senza l'oggetto __proto__, non hanno una proprietà .constructor questo significa qualcosa per chiunque.

Ho pensato di utilizzare Nodes VM ma questo è troppo severo in quanto voglio che l'utente sia in grado di installare i moduli tramite npm e usarli.

Il più vicino che ho effettivamente venire è la creazione di un nuovo modulo (dal momento che non posso mettere un file di nome fs.js nella mia cartella node_modules e richiederlo, ma semplicemente viene ignorato) e appena duro impostando i valori di fs a quello che voglio, ma questo non è giusto, voglio che l'utente usi require('fs') e usi la mia funzione personalizzata.

Questo è possibile senza compilare la mia versione di Node JS?

+0

Non ho lavorato con node.js, quindi potrebbe non funzionare affatto. Si può provare a vedere quale funzione dichiara 'FileSystem' e quindi usarla come prototipo per il proprio oggetto personalizzato (" sottoclasse "esso). MyFS = {FileSystem.call (this);}; MyFs.prototype = new FileSystem(); Oppure usa qualcosa come goog.base e goog.inherit per creare una sottoclasse che possa chiamarle funzioni "parent" e si occupa dei parametri passati al costruttore: http://docs.closure-library.googlecode.com/git/closure_goog_base. js.html Nota che badse usa 'arguments.callee.caller' che non funziona in ecma 5 strict, quindi devi riscriverlo. – HMR

+0

Un buon articolo su goog.base e goog.inherits è qui: http://bolinfest.com/essays/googbase.html – HMR

+0

Ho fatto 'FileSystem' su per scopi illustrativi, i moduli non hanno un oggetto' __proto__' e quindi nessun costruttore. Il più vicino che ho ottenuto è di impostare direttamente le proprietà sull'oggetto e includendo un altro script ma voglio 'require ('fs')' e ha la mia funzionalità personalizzata –

risposta

11

Mi sento in dovere di avvertirti severamente contro le funzioni native di override. Detto questo, questo funzionerà:

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); 
    }); 
}; 

Avrai bisogno di avvolgere lo script per l'utente con il proprio per sostituire prima ciò che si desidera.

+0

+1 Per l'avviso. Non scherzare con i moduli di base. – aggsol

+0

Lo so, non lo farei personalmente. Non almeno senza 'vm' ma è una domanda interessante. Questo però è lo stesso di quello che ho già provato e non è esattamente ciò che vuole. –

+0

@Laurent qualsiasi motivo particolare per evitare l'override delle funzioni native? Sto pianificando di fare qualcosa di simile a sovrascrivere le letture e le scritture del database. – DanMatlin