Node.js understand the function wrapper

Node.js understand the function wrapper

Node.js is wrapping file code with function wrapper which looks like this.

(function(exports, require, module, __filename, __dirname) {
   // nodejs file code actually here
});
Suppose your node js file is first_node.js and its content is as follows:

const os = require('os');

function getTempDir() {
   return os.tmpdir();	
}

module.exports.getTempDir = getTempDir;

Now, you will think how you are able to use exports, require, module, __filename and __dirname in your node js file.

Answer is your file is wrapped in function. So, assume you are writing code in function and your code is able to use all function arguments. This is what actually happens.

Nodejs is achieving following things by doing this:
As you understood your code is wrapped in function so top level variables defined with var, let and const scoped to that module and not become the global object.

__dirname: It will give you directory name of the current module.
Suppose your file is at: /home/galitein/project/example.js
You are writing console.log(__dirname) in example.js then output will be: /home/galitein/project

__filename: It will give you file name of the current module.
Suppose your file is at: /home/galitein/project/example.js
You are writing console.log(__filename) in example.js then output will be: /home/galitein/project/example.js

Let's understand difference between exports and module.exports.

Example 1:
We are taking 2 files file.js and run.js

// --  file.js
exports.myfunction = function() {
  console.log('I am myfunction.');
};

// -- run.js
const file = require('./file');
// let's see what's there in file variable
console.log(file); // {myfunction: Function}
hello.myfunction(); // I am myfunction.

Now, In file.js if you change module.exports.myfunction instead of exports.myfunction then you will see same output.

Then what is the difference? Let's see another examples.

Example 2:
If you export something to module.exports and then you directly export to exports then everything on exports will be ignored.

// -- file.js
module.exports = {
  print: function() {
    console.log('print');
  },
};
// This will not exported.
exports.print = function() {
  console.log('print');
};

Example 3:

// file.js file
exports = {p: 1};

// run.js
const file = require('./file');
console.log(file);

Here we are reassigning export variable so it will not work.

Follwing code will work:

// file.js file
module.exports = {p: 1};

// run.js
const file = require('./file');
console.log(file);