Export

  • 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 export
module.exports = x
 
 
// For multiple exports
module.exports.y = y;
module.exports.z = z;
// OR
module.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 import
const x = require('./path');
 
// multiple exported (as an object)
// import by destructuring
const {y, z} = require('./path');

CommonJS

Internal working

  • 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.js
function Greet() {
	this.greeting = "Hello";
	this.greet = function() {
		console.log(this.greeting)
	}
}
 
module.exports = new Greet();
 
 
 
/////// app.js
const g = require('./greeting.js');
g.greet(); // Hello
g.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 object
const g2 = require('./greeting.js');
g.greet(); // Hola