Petah
Petah

Reputation: 46060

NodeJS run all includes in the same scope/context

I am trying to convert a JS app that was built using the V8 (D8) binaries to Node.

In V8 you could simply load('path/to/file.js'); and it would include the file in the same scope as the current context.

The files that are included have many global variables and functions. I don't really want to go and rewrite all of them (hundreds of files, thousands of lines) to use Node's module pattern.

They also need to both read and write the variables in the global scope.

So how can I include a file in Node but under the same scope/context.

Here is an example of the scripts:

bootstrap.js:

var entityID = 12345;
load("environment.js");
function readEntity(id) { ... }
load("config.js");
writeEntity(entity);

environment.js:

function writeEntity(entity) { ... }
entityID += 1;

config.js:

var entity = readEntity(entityID);

D8 info: http://www.sandeepdatta.com/2011/10/using-v8-javascript-shell-d8.html

Upvotes: 1

Views: 886

Answers (1)

Bret Copeland
Bret Copeland

Reputation: 24050

Register a global load function as the very first bit of code in your program:

var fs = require('fs');

global.load = function (file) {
    var body = fs.readFileSync(file, {encoding:'utf8'});
    eval.call(global, body);
};

Calling load('./file.js'); from anywhere in the code will cause the file to be loaded as part of the global scope. Even if you provide a different scope to eval.call(), the code still seems to end up being global. I'm not sure there's really a good way to limit the scope to a single module unless you call eval directly in-place (instead of through a load function).

You may also want to put in a conditional which prevents the same file from being 'loaded' twice, if that's a concern.

Lastly, even though you said you didn't want to, rewriting the code for the module paradigm may very well be worth it in the long run for manageability. I wouldn't just outright reject it.

Upvotes: 2

Related Questions