Home  Nodejs   Export vs e ...

export vs exports in nodejs modules

In Node.js and JavaScript modules, export and exports serve different purposes and are used in different contexts. Here’s an explanation of each, along with examples to help clarify their usage:

export

The export keyword is used in the context of ES6 modules. It is part of the ECMAScript 2015 (ES6) module syntax and is used to export functions, objects, or primitives from a module so that they can be imported into other modules with the import keyword.

Syntax

Named Exports:

// module.js
export const foo = () => { ... };
export const bar = () => { ... };

// main.js
import { foo, bar } from './module.js';
foo();
bar();

Default Export:

// module.js
const myFunction = () => { ... };
export default myFunction;

// main.js
import myFunction from './module.js';
myFunction();

Combining Default and Named Exports:

// module.js
const mainFunction = () => { ... };
const auxiliaryFunction1 = () => { ... };
const auxiliaryFunction2 = () => { ... };

export default mainFunction;
export { auxiliaryFunction1, auxiliaryFunction2 };

// main.js
import mainFunction, { auxiliaryFunction1, auxiliaryFunction2 } from './module.js';
mainFunction();
auxiliaryFunction1();
auxiliaryFunction2();

module.exports and exports

In Node.js, which traditionally uses the CommonJS module system, module.exports and exports are used to export values from a module. They are not part of the ES6 module syntax but are specific to Node.js.

Syntax

Using module.exports:

// module.js
const myFunction = () => { ... };
module.exports = myFunction;

// main.js
const myFunction = require('./module.js');
myFunction();

Using exports:

// module.js
exports.foo = () => { ... };
exports.bar = () => { ... };

// main.js
const { foo, bar } = require('./module.js');
foo();
bar();

Note: exports is simply a reference to module.exports at the start of the module, but reassigning exports directly does not change module.exports.

Example

Correct usage of exports and module.exports:

// module.js
exports.foo = () => { ... };
exports.bar = () => { ... };

// OR

module.exports.foo = () => { ... };
module.exports.bar = () => { ... };

Incorrect usage that can cause issues:

// module.js
exports = {
  foo: () => { ... },
  bar: () => { ... }
};

// main.js
const myModule = require('./module.js');
console.log(myModule); // This will be an empty object because exports no longer refers to module.exports

Combining module.exports and exports

You can mix module.exports and exports, but it’s important to understand their relationship. exports is a shorthand for module.exports and should not be reassigned directly if you want to preserve the reference.

Example of combining:

// module.js
module.exports = () => { ... }; // default export

exports.foo = () => { ... }; // named export
exports.bar = () => { ... }; // named export

// main.js
const mainFunction = require('./module.js');
const { foo, bar } = mainFunction;

mainFunction();
foo();
bar();

Practical Example of Socket.IO Export

To understand how Socket.IO uses these concepts, here’s the relevant part of Socket.IO’s code:

const Server = require('./server'); // Assuming Server is defined in another file
const Namespace = require('./namespace');
const Socket = require('./socket');

module.exports = (srv, opts) => new Server(srv, opts);
module.exports.Server = Server;
module.exports.Namespace = Namespace;
module.exports.Socket = Socket;

In this example, module.exports is used to export an anonymous function as the default export. Additionally, module.exports.Server, module.exports.Namespace, and module.exports.Socket are used to export named members.

Published on: Jun 25, 2024, 10:40 PM  
 

Comments

Add your comment