Using require without export

Could someone explain what is happening with this code? In other words, how does require work when not used with export.

We almost always see require() being used with module.exports, but you don't have to. When you don't export anything, the code in the imported module will still run, but you can't bind the import to a variable and interact with it.

Consider the following Foo.js module :

var foo = {};

foo.greet = function(){
    console.log('Hello from Foo!');
}

foo.greet();

I can import this module in my main file, like so :

require('./foo');

If I run this main file, the code inside the Foo.js module will run, and Hello from Foo! will be printed to the console.

However, I can't interact with the foo object directly. The following code will not work :

require('./foo');
foo.greet(); //ReferenceError, foo is not defined

I can bind the module import to a variable, but even this will not work :

var foo = require('./foo');
foo.greet(); //TypeError, foo.greet is not a function

To get it to work, I need to export the foo object from my module, using the module.exports that you are familiar with.

This demonstrates that you don't need to export anything from your modules, just like you don't need to bind the imported module to a variable when you are requiring it. The difference is that you won't be able to interact with the code in the imported module, if you don't export what you don't want to make visible in that module.

In the code in your question, importing Redis works because that module is self-contained, you don't need to interact with it in your code. You only need to import the code so that it can run (require the main Redis module and create the client)


Besides requiring a module that doesn't include exports to run it's side effects it's also possible for a module to define variables in the global scope which can be accessed in the file where the module is required. This happens by defining variables without the var keyword. It's not a good or common practice, but you might encounter it somewhere so it's good to know what is going on.

Example:

// foo.js
bar = 5;

And

// test.js
require('./foo');

console.log(bar);
// prints 5

If barwas defined as:

var bar = 5;

it would be in the module scope and not be accessible in test.js.