DEV Community

Surjoyday Talukdar
Surjoyday Talukdar

Posted on

What happens each time that we require a module by calling the require function with the “module” name as the argument.

what-happens-when-we-rquire-a-module-steps

  1. First the path to the require module is resolved and the file is loaded.
    requiring-and-loading-module

  2. After the module is loaded, the modules code is wrapped into a special function which will give us access to a couple of special objects.
    wrapping-module

The NodeJS runtime takes the code of our module and puts it inside an IIFE (the wrapper function is an IIFE), so it means Node does not directly execute the code that we write in the module and that we required using the require function, but instead its the “ wrapper (IIFE) function” that will contain our code in it’s body and will then execute our code . The “wrapper IIFE” is also the one that passes the “exports”, “require”, “module”, “__dirname” “__filename” into the module (file) and that is why in every module we automatically have access to stuff like the require function.

→ By doing this Node achieve 2 important things :

i. Firstly doing this gives developer access to all the variables like “require”, “__filename”, etc.
ii. Secondly it keeps the “top-level variables ( variables declared outside of any function )” that we define in our modules private, so scoped only to the current module, instead of leaking everything to the global object.

Example : If we have 2 modules and we export module 1 to module 2 then all the top-level variables of module 1 are now scoped inside the wrapper function of the module 2 instead of leaking the everything from the module 1 into the global object. It promotes modularity, prevents naming conflicts, and offers controlled access to functionalities within modules

math.js (Module 1):

// Top-level variable (private)
const PI = 3.14159;

function add(a, b) {
  return a + b;
}

exports.add = add; // Expose the add function
Enter fullscreen mode Exit fullscreen mode

app.js (Module 2):

const math = require('./math');

console.log(math.add(5, 3)); // Output: 8 (using the exported function)

// Cannot access PI directly from math module
// console.log(PI); // This would result in an error

Enter fullscreen mode Exit fullscreen mode

3.After that the code in the module’s “wrapper function” is EXECUTED by the Node.JS runtime.

4.Now after the code execution it time for the “require” function to return something and whats returns is the exports of the required module. This exports are stored in the “module.exports” object

returning-exports
→ When to use “module.exports” or simply “exports

i. We use module.exports to export single variable, e.g. one class or one function and set it equal to the variable (module.exports = Calculator )
ii. We use exports when we want to export multiple named exports like multiple function, for example , exports.add = (a+b) => a+b

5.And finally the entire module gets “Cached” after the first time they are loaded, meaning if we require the same module multiple times we always get the same result and the code and modules is only executed in the first call , in subsequent calls the result is then retrieved from the cache.

Top comments (0)