Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node JS override standard module

Friend has asked an interesting question and I've tried a few things but to no avail, is there any way to override a Node JS module?

For instance, I want to override the readFile function to use an S3 bucket instead of the filesystem. I.E:

var fs = require('fs');

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

Actually runs something like this

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

I've tried the prototype but it seems they've set up native modules without the __proto__ object, they don't have a .constructor property that means anything to anyone.

I've thought about using Nodes VM but this is too strict as I want the user to be able to install modules via npm and use them.

The closest I've actually come is creating a new module (since I can't put a file named fs.js in my node_modules folder and require it; it just gets ignored) and just hard-setting the values of fs to what I want but this isn't quite right, I want the user to be using require('fs') and use my custom function.

Is this at all possible without compiling my own version of Node JS?

like image 885
Dave Mackintosh Avatar asked Jun 12 '13 19:06

Dave Mackintosh


1 Answers

I feel obliged to strongly warn you against overriding native functions. That being said, this will work:

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

You'll need to wrap your user's script with your own to first override what you want.

like image 108
Laurent Perrin Avatar answered Oct 18 '22 14:10

Laurent Perrin