2013-06-12 19 views
6

Freund hat eine interessante Frage gestellt und ich habe ein paar Dinge ausprobiert, aber ohne Erfolg, gibt es eine Möglichkeit, ein Node JS-Modul zu überschreiben?Knoten JS überschreiben Standardmodul

Zum Beispiel möchte ich die readFile-Funktion überschreiben, um einen S3-Bucket anstelle des Dateisystems zu verwenden. IE:

var fs = require('fs'); 

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

Eigentlich läuft so etwas wie dieses

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

ich den Prototyp habe versucht, aber es scheint, sie nativen Module ohne __proto__ Objekt eingerichtet haben, sie haben keine .constructor Eigenschaft das bedeutet alles für jeden.

Ich habe über die Verwendung Nodes VM gedacht, aber das ist zu streng, wie ich möchte der Benutzer in der Lage sein, Module über npm zu installieren und sie zu verwenden.

Der nächstgelegene ich eigentlich gekommen sind, ist ein neues Modul zu schaffen (da ich nicht eine Datei mit dem Namen fs.js in meinem node_modules Ordner ablegen können und erfordern es, es wird einfach ignoriert) und nur schwer Einstellen der Werte von fs zu Was ich will, aber das ist nicht ganz richtig, ich möchte, dass der Benutzer require('fs') verwendet und meine benutzerdefinierte Funktion verwendet.

Ist das überhaupt möglich, ohne meine eigene Version von Node JS zu kompilieren?

+0

Ich habe nicht mit node.js gearbeitet, so dass dies möglicherweise überhaupt nicht funktioniert. Sie könnten versuchen zu sehen, welche Funktion 'FileSystem' deklariert und diese dann als Prototyp für Ihr benutzerdefiniertes Objekt verwendet (" Unterklasse "it). MyFS = {FileSystem.call (dies);}; MyFs.prototype = new FileSystem(); Oder verwenden Sie etwas wie goog.base und goog.inherit, um eine Unterklasse zu erstellen, die sie als "Eltern" -Funktionen bezeichnen kann, und behandelt Parameter, die an den Konstruktor übergeben werden: http://docs.closure-library.googlecode.com/git/closure_goog_base. js.html Beachten Sie, dass badse 'arguments.callee.caller' verwendet, was in ecma 5 nicht funktioniert, also müssen Sie das neu schreiben. – HMR

+0

Guter Artikel über goog.base und goog.inherits ist hier: http://bolinfest.com/essays/googbase.html – HMR

+0

Ich habe 'FileSystem' zu illustrativen Zwecken gemacht, die Module haben kein' __proto__' Objekt und also kein Konstruktor. Der nächste, den ich bekommen habe, ist, Eigenschaften direkt auf dem Objekt zu setzen und ein anderes Skript einzufügen, aber ich will 'require ('fs')' und es hat meine benutzerdefinierte Funktionalität –

Antwort

11

Ich fühle mich verpflichtet, Sie stark davor zu warnen, native Funktionen zu überschreiben. Davon abgesehen, wird diese Arbeit:

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

Sie werden Ihre Benutzer-Skript mit Ihrem eigenen zum ersten wickeln müssen außer Kraft zu setzen, was Sie wollen.

+0

+1 Für die Warnung. Verwechseln Sie nicht die Basismodule. – aggsol

+0

Ich weiß, ich würde nicht persönlich. Nicht zuletzt ohne 'vm', aber es ist eine interessante Frage. Dies ist jedoch das gleiche wie das, was ich bereits versucht habe und nicht ganz das ist, was er will. –

+0

@Laurent einen bestimmten Grund zu vermeiden, überschreiben native Funktionen? Ich plane, etwas Ähnliches zu tun, um Datenbanklesungen und Schreibvorgänge zu überschreiben. – DanMatlin