Node.js module.exports vs. exports

Learn via video courses

Overview

When we build big applications in javascript, we want to split that into multiple files, for which we have modules. To use such modules in our application we need to export the classes or functions present inside the module. So in this article, we will be looking at two of the most common ways to export functions or classes from modules i.e., module.exports and exports. We will also look into the differences between them and learn which way is best suited for a given case.

Introduction to Modules

Let's first understand modules in javascript, you can understand modules as a file that encapsulate a block of code to facilitate related functionality to the application. Modules break down the complex long piece of code of any application into smaller parts for easy debugging and management. Modules also help in the re-usability of code.

Furthermore, you will come across three types of modules in Node.js:

  1. Core Modules: These are built-in modules like http, fs, etc.
  2. Local Modules: These modules are locally created by the programmer.
  3. Third-Party Modules: These modules are available to use after installation using NPM(Node Package Manager) like: express, mongoose etc.

What are Different Module Formats?

Initially, for a long time, JavaScript existed without the concept of module syntax. That wasn’t a problem, because initially, scripts were small and simple, so there was no need.

But eventually, scripts became more and more complex, so the javascript developer's community came up with a variety of module formats i.e., syntax to organize code into modules and special libraries to load modules on demand. Let's look into some of the popular module formats available to us:

  • AMD (Asynchronous Module Definition): It is a pattern to define and consume modules. It is implemented by the RequireJS library and is mostly used in browsers. AMD provides a defined function to define the module and for consuming the module in the application AMD provides require function.
  • CommonJS Format: This module format is implemented by Node.Js. By default, each .js file is a CommonJS module. A module variable and an export variable are provided for a module to expose APIs. And to load and consume the module in the application, a required function has been provided by the CommonJS.
  • UMD (Universal Module Definition): Similar to the above two module formats it is also a pattern to define and consume module but the set of patterns in this module format makes our code file work in multiple environments. For example, the UMD format is compatible with both AMD (Asynchronous Module Definition) and CommonJS so it can be used in the browser as well as in Node.js.
  • ES6 (ECMAScript 6) module format: After all the module mess, in 2015, JavaScript’s spec version 6 introduces one more different module syntax. This spec is called ECMAScript 2015 (ES2015), or ECMAScript 6 (ES6). The main syntax is the import keyword for importing modules into the application and the export keyword for exporting objects from the current module.
  • SystemJS module: It is a library that can enable ES6 module syntax for any older ES. For example, If the current runtime, like an old browser, does not support ES6 syntax. One solution is to transpile the old module definition to a call of SystemJS library API, System.register.

Note: This article deals with the CommonJS module format (the standard module format for Node.js). module.exports and exports are exporting keywords for CommonJS module format.

:::

Why are Modules Required in Node.js?

  • Modules make our code reusable i.e., we can define a module and use it numerous times as per our needs.
  • Since different codes having different functionalities are present in different files called modules, it's easier to maintain the large code base.
  • Using modules in our application also helps in easy debugging of code as we have to focus only on the module causing the error, not the complete code.
  • Node.js already comes with a set of built-in modules that we can use in our code without having to install them. To do this, we need to require the module to use the required keyword and assign the result to a variable. This can then be used to invoke any methods the module exposes.
  • We can make our work easy by installing 3rd party packages (which are a collection of modules) to perform different tasks in our application without having to code them ourselves.

What are module.exports in Node.js?

When we call require in our application, the new module is created. Its initial value is an empty object literal {}. Before the referenced module’s code is executed, Node.js will wrap it with the module wrapper function. Let's look briefly into the structure of the module wrapper function:

Using the module wrapper function, Node.js keeps top-level variables (defined with var, const, or let) scoped to the module rather than as the global object. It also provides access to the exported module-specific variables for use in our application.

The variables __filename and __dirname in the module wrapper function contain the absolute filename and directory path of the module.

By going through the structure of the module wrapper function you must have got a decent idea of how modules work in Node.js.

Now let's look into module.exports, module.exports is the object reference that gets returned when we make require() calls in our application. By module. exports, we can get access to module-specific variables that don’t leak out to the global object.

Example Program with the module.exports:

msg.js

app.js

Output:

What are Exports in Node.js?

Well, You can consider exports as an alias to module. exports. It acts as a reference to module. exports. Using exports instead of module. exports is handier. Also exports follows destructured assignment (i.e., it allows you to extract individual exported items from the module), so we can choose the objects to be imported. Look at the example below to understand it:

Example Program with exports:

msg.js

app.js

Output:

Explanation: In the above program we imported only two functions in our application app.js from our module msg.js. So exports can support destructuring assignments. Here we also observed that we can also use exports multiple times in our module.

But are these the only difference between exports and module. exports?

To understand the answer to this question, let's first take a look at what the module object is all about.

msg.js

Output:

Notice the third property in the output for the module object i.e., exports: {}. This property is currently an empty object as we have not exported anything from the module msg.js yet. In this property, you will find the 'importable' objects of your module.

For Example:

msg.js

Output:

You can now notice that the exports property has now three objects which have been exported from the module msg.js.

exports in Node.js

Now let's look at the scenario when we use exports and module.exports in the same module to export objects. exports will be able to export objects from the module until we assign anything directly to module.exports. Let's look at the example below to get a better understanding:

Example:

Output:

Explanation: In the above example, you can observe that the exports property in the above output has only one object which is being exported by module.exports, which means exports are no longer a reference to the module. exports, and exports lose all their power to export any object.

Key Difference Between Module. exports and Exports

module.exportsexports
We can call module. exports only once in our module.We can call or use exports multiple times in our module.
It is the object reference that gets returned from the require() calls.exports are not returned by require(). It is just a reference to the module. exports.
We can not cherry-pick some particular objects which we need to import in our application i.e., we will have to import the complete module.Using destructuring assignment, we can cherry-pick some particular objects which we need to import into our application.

Looking to excel in backend development? Scaler Topics Free Node.js course is your gateway to becoming a skilled server-side programmer. Enroll today!

Conclusion

  • Modules are encapsulated blocks of code that are used in the external application based on its related functionality.
  • ECMAScript 6 (ES6) is the official standard module format for javascript. The filenames have an extension as .mjs.
  • CommonJS is the standard module format for Node.js. The filename has an extension as .js.
  • Modules help in reusability, easy maintenance, and easy debugging of code in our application.
  • module.exports acts as the object reference that gets returned from the require() calls.
  • exports is almost similar to module.exports. It is a reference to module.exports.
  • exports is neatly structured code with a better look and is comparatively easy to implement.
  • exports supports destructuring assignment, using this we can cherry-pick some particular objects which we need to import into our application.
  • If any object is assigned directly to module. exports, then exports can not be used to export any object from that module as it no longer refers to module. exports.