Why do we need to pass module.exports as a parameter, since we are already passing the module as a parameter?

I read several online Node.js tutorials. I realized that when using the require(./file-path) function, the node gets the contents of this file and wraps it inside the calling function

 (function(exports, require, module, __filename, __dirname) { // content }()) 

I understood the difference between exports and module.exports . This is all I can see on the Internet looking for the above question. But what is my question, why do we need to pass module.exports and module to IIFE wrapper? We could go through module one, and then get module.exports from it. Are there any advantages to this? Usually, when we pass an object to a function, we do not need to pass object.property .

+5
source share
2 answers

Answer: historical reasons.

You're right, we may only need module and exports , but they still exist for backward compatibility.

There used to be a time when the module shell was changed in almost all fix releases.

In Node 0.1.11, the module wrapper was:

 var wrapper = "function (__filename) { "+ " var onLoad; "+ " var onExit; "+ " var exports = this; "+ content+ "\n"+ " this.__onLoad = onLoad;\n"+ " this.__onExit = onExit;\n"+ "};\n"; 

See: https://github.com/nodejs/node/blob/v0.1.11/src/node.js#L167#L177

As you can see, exports was the same as this , with which the wrapper function was called. You could not exchange it with a new object, and you could not even add some reserved keys to it - for example. you cannot safely export a property named __onExit .

Then at 0.1.12 it was:

 var wrapper = "function (__filename, exports) { " + content + "\n};"; 

See: https://github.com/nodejs/node/blob/v0.1.12/src/node.js#L243-L245

Here, exports was an object provided as one of the arguments, but you could not exchange it for a new object, you could add or remove only the properties of the object that you had.

Then 0.1.13 was the first to have this, i.e. require and include :

 var wrapper = "function (__filename, exports, require, include) { " + content + "\n};"; 

See: https://github.com/nodejs/node/blob/v0.1.13/src/node.js#L225-L227

Then 0.1.14 was the first one to have __module (with underscores) in the wrapper (and this dropped include ):

 var wrapper = "var __wrap__ = function (__module, __filename, exports, require) { " + content + "\n}; __wrap__;"; 

See: https://github.com/nodejs/node/blob/v0.1.14/src/node.js#L280-L284

And 0.1.16 was the first to have a module argument in the wrapper (without underscores):

 var wrapper = "var __wrap__ = function (exports, require, module, __filename) { " + content + "\n}; __wrap__;"; 

See: https://github.com/nodejs/node/blob/v0.1.16/src/node.js#L444-L448

After that, it was changed many times, but this is the time when module introduced, as a result of which exports no longer needed, but still a useful shortcut that allows you to use:

 exports.a = 1; exports.b = 2; exports.c = 3; 

instead:

 module.exports.a = 1; module.exports.b = 2; module.exports.c = 3; 

although in practice, if there were no exports , then they usually write:

 const exports = module.exports; exports.a = 1; exports.b = 2; exports.c = 3; 

or more likely:

 module.exports = { a: 1, b: 2, c: 3, }; 

or, to have some checks in static analysis tools:

 const a = 1; const b = 2; const c = 3; module.exports = { a, b, c }; 

There are many ways to do this; this is a fairly flexible mechanism.

+3
source

Initially, these were only exports and require . Later, module was added backwards in a compatible way to (among other things) completely overlap the export object.

+2
source

Source: https://habr.com/ru/post/1270433/


All Articles