Archive for August, 2021

In the previous post we had discussed about circular dependency in Node.js modules using CommonJS modules specification.Here we will examine the behaviour of Node.js modules using ES Module specification.

We will use the same sample as used in the previous post with the the two modules modulea and moduleb cross reference each other leading to a circular dependency.

image

image

These files has following lines of code as shown below:

image

image

image

The output of the app.js program is quite different what we saw in case of CommonJS modules.

  • The circular dependency is tracked
  • The value of the counter variable is consistent in both the cases.

image

The main reason behind this is the difference in module loading process in case of ES module. It is done in three phases as shown below where dependency resolution and initialization of the exported variables are handled separately.

image

In this post we will examine how the module initialization in Node.js is affected by the circular dependencies ( we will restrict this discussion to the CommonJS specification based module system)

I have created this simple system with three files, the main file app.js and other two modules modulea.js and moduleb.js

image

The two modules modulea and moduleb cross reference each other leading to a circular dependency.

image

I have put together few lines of code to check how the loading works as shown below.

image

image

image

The program produces the following output:

image

Let’s note the discrepancy, a.b.counter is 2 while b.a.counter is 1. This is due to the circular dependency and loading sequence of the modules as shown in the flow chart below.

Untitled

b.a.counter value is 1 as the moduleb is loaded from the cache into app.js ( moduleb is already loaded while loading modulea and cached).

If we switch the sequence of initialization value will get altered as shown below:

image

image

module.exports vs exports in Node.js

Posted: August 14, 2021 in Node.js
Tags: ,

Let’s start by developing a simple ( or sample) Node module as shown below.

image

The file mymodule.js contain the following lines of code to expose two functions with the properties a and b using the exports variable.

image

This module is loaded using the require function as shown below.

image

A very simple code with Node.js module and produces the following output.

image

Now, I will change the code in mymodule.js and app.js as follows:

image

image

The program output now changes and properties a and b are no longer available publicly from app.js.

image

So what’s going on in here ? What’s the difference between module.exports and exports ?

module.exports is the variable used by the require function to expose a public property or an API. This variable is actually returned to the calling scope.

The exports variable is just holds a reference to module.exports.

image

So initially they refer to the same object. But if module.exports is directly assigned a value then that value gets returned to the caller’s scope only.

image

The following code will also not work.

image

This will lead to the following error.

image

This is because re-assigning the exports variable to a different object will not have any impact on the contents of the module.exports variable and none of the properties will be publicly exposed to be used by the caller.

This might look a bit confusing. The exports variable is just an alias to expose the public APIs conveniently. If it becomes too much confusing its better to use module.exports.

image