NodeJS require all modules in one file, good practice?

3k views Asked by At

I am wondering if there is any downside, from a design or security point of view, having one file that requires() all the modules that I need, and then exports them. This would save me to keep track of all modules in every single file.

Example:

// my_requires.js
const bodyParser = require('body-parser')
const parseForm = bodyParser.urlencoded({extended: false})

const DOMPurify = require('dompurify');
const {JSDOM} = require('jsdom');

const jwt = require('jsonwebtoken');
const passport = require('passport');
require('../config/passport')(passport)

module.exports = {
    bodyParser: bodyParser,
    parseForm: parseForm,
    jwt: jwt,
    passport: passport,
    bcrypt: bcrypt
}

and then in any file where I need them, I would just need to

const reqs = require('my_requires.js')

I couldn't figure out if there is any downside in using a construct like this. Since the modules are all loaded into the global space I don't see any downside of my approach?

2

There are 2 answers

1
jfriend00 On BEST ANSWER

For good modular design that makes modules easiest to reuse in other projects, a module should include ONLY the things that it needs itself or that it absolutely has to share with others.

It shouldn't require in things for some other module just to save a few letters of typing somewhere else. There's just no reason to do that. Modules are cached by the system so using a require() in a module where it is needed rather than getting an export from some other file makes the module more stand-alone, more independent and reduces unnecessary dependencies.

So, if you require() everything in one place and then export that around, you just create a gigantic interdependent project where nothing stands independent of anything else. No single module can be reused by itself in some other project because everything depends upon the core app file which is app-specific. And, what did you actually gain by getting rid of module independence? Probably just saved a few lines of typing - that's all.

It is somewhat counterintuitive when coming up to speed in node.js from other programming environments that don't implement modularity the way node.js does, but each module should start with a list of require() statements for the external libraries that it depends on. Yes, some of that code will be duplicated in other modules, but I don't think of it as unnecessary duplication, but rather as an organized statement of dependencies in the interest of clarity and modularity. Here's what this module depends on. Here's what must be installed in order to reuse this module. Here's how to use this module independent of the rest of the app.

I couldn't figure out if there is any downside in using a construct like this. Since the modules are all loaded into the global space I don't see any downside of my approach?

Nothing is black and white. Sometimes there are reasons to share a group of things. But, I'd list these downsides to your method and I would generally avoid the technique:

  1. Reduces module independence and module reusability.
  2. Makes module dependencies less obvious when looking at the code.
  3. Makes modules harder to test independently.
  4. Creates unnecessary interdependencies between files that don't need to depend upon each other for loading things they want to use.

There are occasionally cases where you find that there are a common set of modules that a lot of your modules need all at once. In that case, don't export them from the app into everything. Instead, make a new shareable module that imports those other modules and exports them. Then, you've kept your core modules independent and made a new reusable module that gets you a group of modules you commonly use together. In this way, you solve the same problem by increasing modularity and reusability rather than by reducing it (and you get to save some typing too).

0
David Vicente On

This are the typical things I do in the server file. But, most of them are used only once or twice in my code, and usually in the server file. So, Only if they are used in a lot of places could make sense to me to put it in a separately file. Other case I think it is duplicate code.