in realier days I saw somewhere that we can configure node-js to execute a loaded module in the global scope, I can't find how to do that now.
Why I'm asking?
I have some legacy files that define language utilities that I want to use on both the server and on the client, however many of these utilities are defined as global scope functions.
For example, I have functions like closure(fClosure)
, module(fModule)
, and many more that simply organize your code in readable definitive way, and utilities like $sb(arg,arg,arg)
, that is a string builder, and so on.
Now these utilities are defined in a file like core.js
, and this file is loaded into the browser as first dependency, and life are good.
But, requiring this file in the root helps in places where it extends Array.prototype
, but it functions that are defined in it are not visible in other modules.
(and please avoid the discussion of polluting or colliding with other libs)
I know it's not according to the CommonJS specifications... but now I'm just trying to leverage this legacy codes without reorganizing all the codes in a CommonJS way.
I aslo found about RequireJS and the beautiful AMD model it proposes, but it answers only on how to run on the browser codes that are written for node.js, and not vice-versia.
Assigning to the global variable will not work, because it means I have to rewrite all the legacy libraries.
I am looking for a way to make them run on the global scope and leave all what they declare there, without rewriting them.
So, is there a way to ask node to require a file and run it on the global scope?
You can assign something to the global
object, which for Node is like window
is for the browser, example:
test.js
global.my_var = require('./my_module');
require('./display_my_var');
my_module
module.exports = "this is a string";
display_my_var.js
console.log(my_var); // this will work, as my_var is now global
what we did
This answer is by no mean a good example - as stated above - the case is not healthy in the first place.
The minimal changes we got to apply to our code is listed bellow. Learn from it what you may.
1 - refactor all legacy web codes to declare globals without var.
before:
var MyUtils = { ... };
window.some = value;
after:
MyUtils = { ... };
some = "value";
2 - declare all global functions as assigned global var
before:
function foo() { ... }
after:
foo = function() { ... }
3 - resolve conflicts between legacy codes and new node codes
Well, this one is private, so no snippets about that. But here's snippets about other stuff:
Things you should consider:
properties augmented to prototypes of global classes. If you do it on any of the sides - both now should co-exist with it. Silly example - add()
- like push, but returns the array
Array.prorotype.add = function(s){ this.push.apply(this, arguments); return this }
minifications - we had to solve one place that did not minify well - just had to find a way to put it in code differently, and off with that.
- Unit-testing - every such global should be expected to exist and be excluded from global-scope pollution checks. Once having this full list - we're off with it again (and now it's better documented too :) )
Also worths metnioning
Along the searches we met some cool sandboxing utilities.
Sandboxing means run the code in a sandbox context. that should prevent it from getting to other scopes.
Implementations of this varry.
The one that won my appreciation the most is this: https://github.com/hflw/node-sandbox
It works by running the 'dirty' code in a child process, and help you wire any communication between the 'pure' code and the 'dirty-legacy'.
The result is a complete separation. e.g - Array.prototype
of the child process is not Array.prototype
of the parent - each of them can augment it as it needs to for his own 'criminal' operations...
Like I said - we never got desperate enough to need it so bad, Since the node codes were pure, and do not use any 'extensions' to built-in types - they did not mind the extensions from old client codes.
But to be honest - once the codes were mixed - everybody in the team started use the extensions that came from the client codes, it becomes messy.