Over-use of require() in node.js, mongoose

Problem

I'm new to Node.js, but quite like the module system and require(). That being said, coming from a C background, it makes me uneasy seeing the same module being require()'d everywhere. All in all, it leads me to some design choices that deviate from how things are done in C. For example:

  • Should I require() mongoose in every file that defines a mongoose model? Or inject a mongoose instance into each file that defines a model.
  • Should I require() my mongoose models in every module that needs them? Or have a model provider that is passed around and used to provide these models.

Ect. For someone who uses dependency injection a lot - my gut C feeling is telling me to require() a module only once, and pass it around as needed. However, after looking at some open-source stuff, this doesn't seem to be Node way of things. require() does make things super easy..

Does it hurt to overuse this mechanism?

Problem courtesy of: Colin

Solution

require() caches modules when you use it. When you see the same file or module required everywhere it's only being loaded once, and the stored module.exports is being passed around instead. This means that you can use require everywhere and not worry about performance and memory issues.

Solution courtesy of: cptroot

Discussion

As cptroot states requiring a module everywhere you need it instead of passing it around as an argument is safe to do and is also much easier. However, you should view any require call as a hardcoded dependency which you can't change easily. E.g. if you want to mock a module for testing these hardcoded dependencies will hurt.

So passing a module instance around as an argument instead of just requiring it again and again reduces the amount of hardcoded dependencies because you inject this dependency now. E.g. in your tests you will benefit from easily injecting a mock instead.

If you go down this road you will want to use a dependency injection container that helps you injecting all your dependencies and get rid of all hardcoded require calls. To choose a dependency injection container appropriate for your project you should read this excellent article. Also check out Fire Up! which I implemented.

Discussion courtesy of: analog-nico

This recipe can be found in it's original form on Stack Over Flow.