Coder Perfect

What is the function of module.exports in Node.js, and how do you utilize it?

Problem

What is the function of module.exports in Node.js, and how do you utilize it?

I can’t seem to locate any information on this, but it looks to be a crucial aspect of Node.js because I see it frequently in source code.

According to the documentation for Node.js:

However, this is ineffective.

What is the purpose of module.exports, and what is a simple example?

Asked by mrwooster

Solution #1

The object that is returned as the result of a need call is module.exports.

Because the exports variable is initially set to the same object (i.e. it’s a “alias”), you’d generally put something like this in the module code:

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

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

You’d use the following in the calling code:

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

The last line demonstrates how the return of require is usually just a basic object with properties that may be accessed.

Please see module.exports for further information. As a result, if you want to assign a new object (or a function reference) to exports, you must also assign it to module.exports.

It’s worth noting that the name you give the exports object doesn’t have to be the same as the value’s internally scoped name in the module, 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

Answered by Alnitak

Solution #2

Although this question has already been answered, I’d want to provide some explanation…

Both exports and modules are available. To import code into your program, use exports like this:

require(‘./path/to/mycode’); var mycode = require(‘./path/to/mycode’);

The most common use case (for example, in the ExpressJS sample code) is to set properties on the exports object in a.js file, which you then import using need ()

As an example, in a simple counting scenario, you could have:

(counter.js):

var count = 1;

exports.increment = function() {
    count++;
};

exports.getCount = function() {
    return count;
};

…then include the following code in your application (web.js or any other.js file):

var counting = require('./counter.js');

console.log(counting.getCount()); // 1
counting.increment();
console.log(counting.getCount()); // 2

In simple terms, needed files are functions that return a single object, to which you can add properties (strings, numbers, arrays, functions, or anything else) by setting them on exports.

You might want the object given by require() to be a function you can call instead of merely an object with properties. In that scenario, you’ll also need to set module.exports to something like this:

(sayhello.js):

module.exports = exports = function() {
    console.log("Hello World!");
};

(app.js):

var sayHello = require('./sayhello.js');
sayHello(); // "Hello World!"

There’s a distinction to be made between exports and modules. This answer explains exports in greater detail.

Answered by Jed Watson

Solution #3

It’s worth noting that the NodeJS module mechanism is based on CommonJS modules, which are supported by SproutCore, CouchDB, Wakanda, OrientDB, ArangoDB, RingoJS, TeaJS, SilkJS, curl.js, and even Adobe Photoshop (via PSLib). The complete list of known implementations may be seen here.

I strongly advise you to utilize exports instead of module unless your module uses node-specific features or module. exports that aren’t part of the CommonJS standard and, as a result, aren’t usually supported by other implementations.

Another NodeJS-specific feature is assigning a reference to a new object to exports rather than merely adding attributes and methods, as in Jed Watson’s previous example in this thread. I would personally oppose this behavior because it violates the CommonJS modules mechanism’s circular reference support. As a result, not all implementations support it, therefore Jed’s example should be written in this (or a similar) approach to give a more universal module:

(sayhello.js):

exports.run = function() {
    console.log("Hello World!");
}

(app.js):

var sayHello = require('./sayhello');
sayHello.run(); // "Hello World!"

Alternatively, you can make use of ES6 features.

(sayhello.js):

Object.assign(exports, {
    // Put all your public API here
    sayhello() {
        console.log("Hello World!");
    }
});

(app.js):

const { sayHello } = require('./sayhello');
sayHello(); // "Hello World!"

PS: Appcelerator appears to support CommonJS modules, but not circular references (see Appcelerator and CommonJS modules (caching and circular references)).

Answered by Alexandre Morgaut

Solution #4

When assigning a reference to a new object to exports and/or modules, there are a few things to keep in mind. exports:

This one should go without saying, but if you add an exported method to an existing module, make sure the native exported object isn’t referencing another object at the end.

exports.method1 = function () {}; // exposed to the original exported object
exports.method2 = function () {}; // exposed to the original exported object

module.exports.method3 = function () {}; // exposed with method1 & method2

var otherAPI = {
    // some properties and/or methods
}

exports = otherAPI; // replace the original API (works also with module.exports)
exports = function AConstructor() {}; // override the original exported object
exports.method2 = function () {}; // exposed to the new exported object

// method added to the original exports object which not exposed any more
module.exports.method3 = function () {}; 
// override the original exported object
module.exports = function AConstructor() {};

// try to override the original exported object
// but module.exports will be exposed instead
exports = function AnotherConstructor() {}; 

Answered by Alexandre Morgaut

Solution #5

the component A module can choose what should be shared with the application using the exports property or the exports object.

Here’s a link to a video about module export.

Answered by anish

Post is based on https://stackoverflow.com/questions/5311334/what-is-the-purpose-of-node-js-module-exports-and-how-do-you-use-it