What Is the Purpose of Node.Js Module.Exports and How to Use It

module.exports vs exports in Node.js

Setting module.exports allows the database_module function to be called like a function when required. Simply setting exports wouldn't allow the function to be
exported because node exports the object module.exports references. The following code wouldn't allow the user to call the function.

module.js

The following won't work.

exports = nano = function database_module(cfg) {return;}

The following will work if module.exports is set.

module.exports = exports = nano = function database_module(cfg) {return;}

console

var func = require('./module.js');
// the following line will **work** with module.exports
func();

Basically node.js doesn't export the object that exports currently references, but exports the properties of what exports originally references. Although Node.js does export the object module.exports references, allowing you to call it like a function.



2nd least important reason

They set both module.exports and exports to ensure exports isn't referencing the prior exported object. By setting both you use exports as a shorthand and avoid potential bugs later on down the road.

Using exports.prop = true instead of module.exports.prop = true saves characters and avoids confusion.

What is the purpose of Node.js module.exports and how do you use it?

module.exports is the object that's actually returned as the result of a require call.

The exports variable is initially set to that same object (i.e. it's a shorthand "alias"), so in the module code you would usually write something like this:

let myFunc1 = function() { ... };
let myFunc2 = function() { ... };
exports.myFunc1 = myFunc1;
exports.myFunc2 = myFunc2;

to export (or "expose") the internally scoped functions myFunc1 and myFunc2.

And in the calling code you would use:

const m = require('./mymodule');
m.myFunc1();

where the last line shows how the result of require is (usually) just a plain object whose properties may be accessed.

NB: if you overwrite exports then it will no longer refer to module.exports. So if you wish to assign a new object (or a function reference) to exports then you should also assign that new object to module.exports


It's worth noting that the name added to the exports object does not have to be the same as the module's internally scoped name for the value that you're adding, so you could have:

let myVeryLongInternalName = function() { ... };
exports.shortName = myVeryLongInternalName;
// add other objects, functions, as required

followed by:

const m = require('./mymodule');
m.shortName(); // invokes module.myVeryLongInternalName

How does exports object reference module.exports in Node.js?

CommonJS modules are actually pretty simple: you take all the code in a file, and just wrap it in a function. Execute the function, and return the value of module.exports after execution to the caller.

You can see this function's header in the node.js source code:

const wrapper = [
'(function (exports, require, module, __filename, __dirname) { ',
'\n});'
];

The wrapper is applied to the code in the require'd file and then called like this:

  const exports = this.exports;
const thisValue = exports;
const module = this;
if (requireDepth === 0) statCache = new Map();
if (inspectorWrapper) {
result = inspectorWrapper(compiledWrapper, thisValue, exports,
require, module, filename, dirname);
} else {
result = compiledWrapper.call(thisValue, exports, require, module,
filename, dirname);
}

As you can see it's pretty straightforward. const exports = this.exports, and then exports is passed as an argument to the wrapper function - thus they initially point to the same value, but if you reassign either then they no longer do.

Why we use exports in nodejs?

TL;DR

You can use:

exports.x = 1;
exports.y = 2;
exports.z = 3;

as a shorter way of writing:

module.exports.x = 1;
module.exports.y = 2;
module.exports.z = 3;

The only advantage is less typing.

But you have to write:

module.exports = {
x: 1,
y: 2,
z: 3
};

as this will not work:

exports = {
x: 1,
y: 2,
z: 3
};

because it wouldn't change the module.exports and it's module.exports that actually gets exported.

Explanation

Your module gets wrapped in an implicit closure that gets some variables passed as parameters. One of those variables is called exports that is an empty object and another one is called module and it includes exports as one of its properties:

module.exports === exports

When you write:

exports.x = 10;

then you change the property of the provided object (the object is still the same object, but it is mutated) and everything is fine. The value x is available as both exports.x and module.exports.x.

But if you write:

exports = {x: 10};

then you assign a new object to exports while the module.exports is still pointing to the original (empty) object. That way you have exports.x set correctly but you don't have module.exports.x set as well, because now:

module.exports !== exports

If you want to make a new object instead of using the empty one that you got in exports then you have to assign it to module.exports:

module.exports = {x: 10};

Now module.exports and exports are different as well:

module.exports !== exports

But it's module.exports that's actually exported so everything is fine.

After assigning a new object to module.exports you could assign it to exports as well:

module.exports = {x: 10};
exports = module.exports;

or do it the other way around:

exports = {x: 10};
module.exports = exports;

so you could still use the shortcut of assigning new properties with:

exports.y = 20;

but I haven't seen that in practice.

Real examples

Exporting some functions (public) but not others (private).
Let's say you have those functions:

function private1() {
// ...
}
function private2() {
// ...
}
function public1() {
// ...
}
function public2() {
// ...
}

You have few options to export two public functions:

This works

module.exports.public1 = public1;
module.exports.public2 = public2;

or:

exports.public1 = public1;
exports.public2 = public2;

or:

module.exports = {
public1: public1,
public2: public2
};

or:

module.exports = {
public1,
public2
};

This doesn't work

exports = {
public1: public1,
public2: public2
};

or:

exports = {
public1,
public2
};

Summary

In other words, exports is just for convenience so that you don't have to write module.exports every time, but it doesn't work for cases when you want to export a different object than the one provided to you originally. In that case you need to set the module.exports to that new object.

See also

See also this answer:

  • What is the difference between module.export and export

Node.js module.exports a function with input

You can use promises to handle the async functions

Try Changing your module.exports to return a promise function

const crypto = require("crypto");
module.exports = function (x, y) {
return new Promise(function (resolve, reject) {
var addition;
crypto.randomBytes(5, function (err, data) {
addition = data.toString("hex");
if (!addition) reject("Error occured");
resolve(x + y + addition);
})
});
};

You can then call the promise function using the promise chain

let e = require("./encryption.js");

e(1, 2).then((res) => {
console.log(res);
}).catch((e) => console.log(e));

Suggest you to read Promise documentation

For node version > 8, you can use simple async/await without promise chain.You have to wrap your api inside a promise using utils.promisify (added in node 8) and your function should use the keyword async.Errors can be handled using try catch

const util = require('util');
const crypto = require("crypto");
const rand = util.promisify(crypto.randomBytes);

async function getRand(x, y){
try{
let result = await rand(5);
console.log(x + y + result);
}
catch(ex){
console.log(ex);
}
}

console.log(getRand(2,3));

where do module.exports export your function and what is the use of it when we still use require to import the code into your module

(#1 and #4 don't need answers, so I've left them off.)

2) But i want to know why we can see a log which we have written in notes.js without using module.exports statment.

With Node.js's style of modules (which is a flavor of CommonJS), a module is loaded and executed when it's first required. Your console.log is in the module's code, so when you require it (the first time), that code gets run.

why can't we use require statment and store total code and call the function from that varable as we do for a instance of a class

You can, if that's what you want to do:

exports = {
// code here as object properties
addNote: () => {
console.log('addNote');
return 'New note';
}
};

and

const mod = require("./notes.js");
mode.addNote();

3)More preciously where do module.export export your code (i mean to which directrey )

To the module cache in memory.

meaning of module.exports= function in node.js

It works exactly the same as the first one does, only that it exports a function instead of an object.

The module that imports the module can then call that function:

var dummy = require('./dummy.js');
dummy();

any idea how can i export variables from module defined like this..?

Since functions are just objects, you can also assign properties to it:

module.exports = function(passport,config, mongoose) {}
module.exports.user = 'rally';

However I'd argue that this is less expected if a module directly exports a function. You are probably better off exporting the function as its own export:

exports.login = function(passport,config, mongoose) {}
exports.user = 'rally';

does module.exports simply binds function to an object?

Two are almost same.
when you use this.

module.exports = {func1,func2,func3}

you have to import like this.

const {funct1,funct2,funct3} = require('./path/to/file');

if you use like this

 module.exports.func4= func1;
module.exports.func5 = func2 ;
module.exports.func6 = func3;

you have to import like this:

const {funct4,funct5,funct6} = require('./path/to/file');

Both are same but when you use first method you have to use the same name wherever you call your function.

But with second method you can use different names.

Hope you get the idea!

How to use module exports correctly in my local app

There are several ways to achieve what you wish. One simple but effective solution is to add an attribute to the global object. This has to be done in your main (entry) js file, before any require statements:

(Paths below are built assuming your entry js file is in the app folder)

global.__runCmdPath = __dirname + '/common/cmd/run-cmd';

Then, in any other module from which you would like to require runCmd you could simply:

const runCmd = require(__runCmdPath);

You could even set, as attribute of the global object, the base directory of the scripts containing the functions you'd like to export, and then just append the single script-name, like:

const runCmd = require(__scriptsDir + '/run-cmd');
const runCmd2 = require(__scriptsDir + '/run-cmd2');

Another strategy would be to add the scripts folder to the NODE_PATH environmental variable, with the following command for UNIX:

export NODE_PATH=./common/cmd

and for Windows:

set NODE_PATH=./common/cmd

Then, you may command node app.js and this way, you will simply be able to require('run-cmd') everywhere. This will work as long as you remember to re-set the variable everytime you start a new shell session.

For what regards TypeError: runCmd is not a function., this will continue to occur if you try to call runCmd directly, from where you have required it. This is because require() returns an exports object, and your exported methods all belong to this object.

If you would like to call the runCmd method you exported, in this case, you'll have to do it this way:

runCmd.runCmd('vcgencmd measure_temp', function(result) {
console.log("Result we are prepping to send: " + result);
res.json({result: result});
});

Thus, you might want to re-name the constant containing your exports object, or the exported name of the runCmd function, to whatever suits you best.



Related Topics



Leave a reply



Submit