Node.js — Modules
Understanding modules and require, exports, and module.exports
If you have been developing applications using Node.js, then you must have used require
and module.exports
. But where do they come from and how do we understand them more? To answer this question, we need to first understand what a module is in Node.js.
What is a module?
A module is a file or folder that contains code. Yes, any file on your computer that contains Node.js code is known as a module.
Why call it a module?
Your next question might be, “why call it a module, when its just a file with some code?”
Node wraps each and every file in a function and passes it 5 arguments. To see these 5 arguments, we can use console.log:
console.log(arguments);
When we put the above code at the top-level of a file and run it via Node, we would see the 5 arguments printed out to the console. These five arguments are as follows: exports, module, require, __filename, __dirname
exports or module.exports is used to define an API of a module.
require is used to require other modules.
__filename contains the path to this file.
__dirname contains the path to the folder hosting this file.
NOTE: These are not global objects, they are arguments to the function that Node wraps around the code in a file before it gets executed by Node.
Now that we know that Node wraps each and every file with a function, we should also note that any top-level variable in this file is NOT global, it is scoped to the wrapping function.
Other than the function receiving 5 arguments, it also returns module.exports
object. module
object is used to manage dependencies and the APIs of modules.
So, in reality, if we have a file that contains one console.log
statement:
console.log(arguments);
Node.js would turn the file to:
funtion(exports, module, require, __filename, __dirname) {
console.log(arguments);
return module.exports
}
require, exports, and module.exports
Now that we know where exactly require
, exports
and module.exports
from, let us better understand each one of this and put it to use!
exports
and module.exports
are basically referring to the same object. At the end of each module, Node.js returns module.exports
object which can be used in other modules by requiring a module.
require
is used to require other modules in the current module you are working with. By requiring other modules, we are basically requiring their module.exports
object.
To see require
and exports
object in action, let us create two files; answer.js
and question.js
. answer.js
would contain an answer to the question asked in question.js
file. Please note that I have created these two files just to demonstrate the use of theexports
object and therequire
method.
As you can see that we are exporting the answer
constant by making it part of theexports
object (remember that Node wraps all the code in the file with a function which then returns module.exports
object), and we are using it in the question.js
by destructuring it from the object that we receive by requiring the answer.js
file.
NOTE: Both of these files should be under one directory.
We can as well assign as many properties as we want to the exports
object:
What else can we export from a module? We can export anything we want; functions, lists, variables, basically anything which you can create with JS you can export it via module.exports
.
By the way, here is the key difference between exports
and module.exports
; when you assign exports
object directly as so: exports = 42
you would be breaking the assignment reference between exports
and module.exports
(in short, exports
would NOT be the same as module.exports
), and nothing would get returned because remember that at the end Node is returning module.exports
and NOT exports
. However, assigning module.exports
directly works perfectly as expected:
Note that we don’t need to deconstruct the answer
variable as we did before because this time we have altered the module.exports
object and assigned it directly instead of adding a property to it.
To wrap this post up, let us see an example of exporting a function from a module as this is the most common way of utilizing modules:
Until next time, Adios my friends!