In essence module.exports only returns whatever you provide it
If you provide directly value, that will be returned
If you provide an object with key and values, then that object is exported
const x = 1;const y = 2;const z = 3;// For single exportmodule.exports = x// For multiple exportsmodule.exports.y = y;module.exports.z = z;// ORmodule.exports = { y: y, z: z}
Import
It really depends on how the values are exported from the file
If directly exported then we can directly import
If it is exported as an object, we can de-structure that object and import it
// single exported importconst x = require('./path');// multiple exported (as an object)// import by destructuringconst {y, z} = require('./path');
CommonJS
CommonJS is a specification to implement modules in javascript
Nodejs use CommonJS specification to implement modules (ES6 import export was not available when Nodejs was invented)
Internally Nodejs wraps the javascript code inside another function and make use of IIFE (Immediately Invoked Function Expression) to mimic import export functionality before passing to V8 engine.
The exact wrapper function looks something like this:
(function (exports, require, module, __filename, __dirname) { // my code starts function add (a, b) { return a + b } module.exports = add // my code ends})
Hence Each file in nodejs hence have access to (These objects are not coming from global object):
exports,
require
module
__filename
__dirname
exports vs module.exports
exports is nothing but shortcut/reference to module.exports
They reference the same object, hence there is an issue:
exports = function() { return 4;}console.log(exports); // [Function]console.log(module.exports); // {}// Although ideally we would think that module.exports will point to the same function but it doesn't happen and instead the reference of exports is re-written causing issue
Calling require() multiple times
Nodejs caches require() results hence calling require multiple times on the same file does not cause execution of require’d file multiple times
For example
//// greet.jsfunction Greet() { this.greeting = "Hello"; this.greet = function() { console.log(this.greeting) }}module.exports = new Greet();/////// app.jsconst g = require('./greeting.js');g.greet(); // Hellog.greeting = "Hola";// This will not create g2 as new object of Greet// caching will be used and hence g and g2 are references of the same objectconst g2 = require('./greeting.js');g.greet(); // Hola