Node.js global require
Asked Answered
F

2

11

how can i require a module globally so i can use it in different modules without having to require it again? or do i just have to do that everytime? is there any best practice for this?

heres an example of what i am talking about. lets say i have an index.js like this:

var a = require('a.js'),
utils = require('utils.js');

var str = 'hello this is a test';
str = a.change(str);

utils.return(str);

a.js

var utils = require('utils.js');

exports.change = function(str) {
    str = str.replace('test', 'example');
    utils.return('i changed test to example!');
    return str;
}

utils.js

exports.return = function (msg) {
    console.log(msg);
}

you see i have to require('utils.js') twice, but i would rather require it once in the index.js and have it available in the index.js and a.js as utils. is there any good way to accomplish that?

Frow answered 3/7, 2015 at 17:4 Comment(1)
I actually have a similar issue as well (https://mcmap.net/q/1016680/-parse-is-undefined-in-node-js-controller). Looking forward to see the answer to your question. It might solve my issue as well.Underwood
T
15

The usual practice in nodejs development is to just require() a module in each module that you need it. The module itself is cached by nodejs so the same module is returned every time and it isn't actually loaded over and over. Doing it this way rather than creating globals generally makes code more modular and reusable since each module uniquely specifies (with require() statements) what it needs rather than having a bunch of modules that depend upon some pre-existing global configuration which creates a lot more dependencies, load order issues, etc...

It is possible to make a single module that does require() on a bunch of other modules and then combines the results into a new master module if that is relevant or useful so other modules only have to require the new master module.

It is not recommended to use globals in place of just using a require() statement. Remember that in nodejs programming, most require() statements are just run at server initialization time and they are cached so there's little reason to avoid the benefits and modularity that using require() instead of globals provides.


I wouldn't personally recommend this because it messes with modularity, but in your specific example, you could also pass the utils module to the a.js constructor:

var utils = require('utils.js');
var a = require('a.js')(utils);
Turnstone answered 3/7, 2015 at 17:12 Comment(3)
thanks for the answer. the problem is, that i have a highly modularized project, and a lot of modules are needed inside of other modules. this results in a huge block of require statements at the beginning of every module i write, which is very ugly in my opinion. i am aware that the required modules are cached, and thats not really my problem. i would just like to get rid of that huge require block in every module.Frow
@JohnJackson - So, you've modularized so much that you now want to unmodularize with a bunch of globals? Can you see the irony here? You're certainly free to use globals if you want and somehow carefully control the loading order - I just don't know of anyone who thinks that is a good design pattern. And, it breaks many of the advantages of modularity in the first place since your modules that use the globals will no longer be self contained and usable on their own (without some host first creating the proper globals).Turnstone
@JohnJackson - FYI, having an easily maintainable, resuable and modular design has some cost to it. In this case, it sounds like you've already designed things into smallish modules. The remaining piece to actually use it that way is to simply insert the necessary require() statements in each module. If you really don't like that, then you're just throwing away most of the advantages of your modularity design (other than having lots of small files). The biggest advantage of modularity is meant to be ease of reuse and if you rely on a bunch of globals, you won't have that.Turnstone
S
1

For people googling this problem in the future you can use the global variable. Only do this in really specific ocasions (eg: code replicated in every file)

global.mymodule = require("mymodule");
mymodule.abc // works in any file in the same process
Satinwood answered 13/2, 2022 at 11:33 Comment(1)
this should be the accepted answer, people who say "you modulized too much"/"the 'modularity' worth adding the duplicate statements" seem like never worked with large unobfuscated codebasesBeady

© 2022 - 2024 — McMap. All rights reserved.