0

I have several "routes" files where I import modules like this:

var bcrypt = require('bcryptjs');

I have attempted to make bcrypt available globally by importing it into my main app js and then using an app.use() something like this:

var bcrypt = require('bcryptjs');
app.use(bcrypt); // clearly not right, app crashes

I've tried a variety of things here. Should I just stick with importing this into every file separately or is there a good way to make this module available globally?

Glenn
  • 4,195
  • 9
  • 33
  • 41

2 Answers2

3

app.use will only work with an Express middleware, which bcrypt is not, it's just a regular Node.js module.

As was pointed out in the comments, there is not really any reason why you shouldn't just use require to make bcrypt available in any module that needs it.

For what it's worth, you can use the globally available variable global to create a global variable in Node.js.

In your example, it would be used like this (but again, this is NOT RECOMMENDED):

var bcrypt = require('bcryptjs');
global.bcrypt = bcrypt;
Patrick Hund
  • 19,163
  • 11
  • 66
  • 95
  • Thank you. What is `global` commonly used for? I ask because I always do try to stick to the DRY principle, but obviously don't want to eff things up along the way. – Glenn Jun 03 '17 at 17:59
  • 1
    I'm not sure, I haven't used it in any of my projects. – Patrick Hund Jun 03 '17 at 18:00
  • @Alan it's not commonly used. I think it's mostly there for the framework to populate things like `__dirname`. – Paul Jun 03 '17 at 20:56
1

Though you've already accepted an answer, I thought I'd describe a lot more about why you don't want to use the global and why it's desirable to just require() in every module that you need.

The concept behind modules is that you should strive to make each module as independently usable as possible. In that spirit, there is no reason at all that you should make a module dependent upon a previous module initializing some global variable. That just makes one module depend upon the exact order of loading with some other module, ruins the ability to ever use that module independently and sets up a potential global variable naming conflict.

A big design goal of the module design in node.js is to avoid using globals. Instead, a module should either just require() in what it needs or it can be passed required data from other modules when it is loaded or it can query other modules for shared data by calling methods in those other modules.

In addition, loading a module with require() is cached. So, only the very first time a module is loaded with require() does it load from disk and execute. Every subsequent time it is loaded, the previously loaded module object is just immediately returned. Thus, it costs almost nothing to load a module more than once from various modules that need access to it.

So, every module that needs access to bcrypt should just do this:

const bcrypt = require('bcrytpjs');

Yes, this leads to repeating a few more things at the top of each module and that does sometimes feel a little less DRY than you might strive for generally, but it is overall a better tradeoff because it keeps modules as independent as possible as each module independently specifies what other modules it depends on and uses no globals to do that.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Worth pointing out that it's logically equivalent to Python and Java `import` and C# `using` and so on. – Paul Jun 03 '17 at 20:59
  • Thanks, so I think my flawed thinking was that my modules (e.g., myroute.js) were like children to the app.js file and so they should have access to everything already in app.js (which is the way many other frameworks are structured). But you're saying that I should look at each of these modules (app.js, myroute.js, etc) as independent of each other? Coming from other frameworks, that is a foreign way of thinking to me, but I see the benefits of avoiding precarious dependencies. – Glenn Jun 03 '17 at 22:31