Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

node.js: Accessing local variables from another module

My Problem

I'm writing a node module called a, which require()s a module b (written by a stranger). Unfortunately, a doesn't only need to access the public members - it also needs to access local variables declared in the scope of the module.

// a
var b = require('b');

console.log(b.public);
console.log(b.private); // undefined


// b
var c = require('c');
var stdin = process.stdin;

exports.public = true;
var private = true;

My Solution

// a
var b = require('b');
var srcPath = require.resolve('b');

console.log(b.public);
fs.readFile(srcPath, 'utf-8', function (err, src) {
    var box = {};
    var res = vm.runInNewContext(src, box, srcPath);
    console.log(box.private);
});

But vm doesn't run b as a module, so require() etc. aren't accessible from the context of the vm. So there are ReferenceErrors like:

    var res = vm.runInNewContext(src, box, scPath);
                 ^
ReferenceError: require is not defined
    at <module b>
    at <module a>
    at fs.readFile (fs.js:176:14)
    at Object.oncomplete (fs.js:297:15)

My Question

Which is the cleanest way to get the value of a local variable declared in another module? Ideas?

Thanks for your help.

like image 742
fridojet Avatar asked Dec 24 '12 10:12

fridojet


People also ask

How do you access local variables outside the scope?

Local variables cannot be accessed outside the function declaration. Global variable and local variable can have same name without affecting each other.

How do you call a function from another module in node JS?

To include functions defined in another file in Node. js, we need to import the module. we will use the require keyword at the top of the file. The result of require is then stored in a variable which is used to invoke the functions using the dot notation.

Can a local variable be used outside a function?

Variables that are declared inside a function or block are called local variables. They can be used only by statements that are inside that function or block of code. Local variables are not known to functions outside their own.


1 Answers

you should probably mostly never have to do this, but there might be reasons.

you can hook the loader and inject javascript code to export what you want.

// let's say you have node_modules/foreignmodule/index.js
// and in that script there is a local (not-exported) function foreignfunction().

var path = require('path');
_oldLoader = require.extensions['.js'];
require.extensions['.js'] = function(mod, filename) {
    if (filename == path.resolve(path.dirname(module.filename), 'node_modules/foreignmodule/index.js')) {
        var content = require('fs').readFileSync(filename, 'utf8');
        content += "module.exports.foreignfunction=foreignfunction;\n";
        mod._compile(content, filename);
    } else {
        _oldLoader(mod, filename);
    }
};

require('foreignmodule').foreignfunction();
like image 195
Moritz Avatar answered Oct 14 '22 01:10

Moritz