In my previous post about Node.js — Dependency Management, we looked at the basics of what is Node.js module. How can we use module.exports and require to work with dependencies. How folder dependencies work and why they are useful. We all look at how the Node.js lookup system works to look for dependencies and some basics of NPM.
Today we will continue from that point and see how we use this module system to break down an application into multiple modules. What are the benefits of doing so and how does Node.js handle this?
I will be using some of the learnings from the previous post, so, if you are here the first time, I will recommend checking the previous post to make this part easy to understand.
But before we continue about application setup with multiple modules, let’s learn a few more other interesting aspects of Node.js modules.
Are Node Modules Singleton?
In the previous post, we talked about that Node loads a module only once and if someone asks for it, Node gives the cached copy of that module. So, yes they behave like singletons. Let’s see an example of this behavior.
To start with I created a project for the application, initialize the application, and created a file user.js as follows:
Now, in app.js I require the user module and used it as follows:
You can see that we created two variables of user, however, changes make to one are reflected to other. The user module is cached and reused when asked for another time. This is something you must be aware of.
Let’s see how it behaves if we change it to a constructor function:
I have changed the implementation of user.js (we learned about the constructor function in the previous post):
And now I use it in app.js as follows:
So, this time, we are getting two different instances and now you can see the difference. Don’t worry about this too much, we will see some more examples and solutions in later posts.
Now, let’s move to our main topic, about managing applications using modules.
We will start building up a foundation for our application structure, we will start simple and refine it as we move forward.
I have created few new folders and moved the files around and now we have the following structure in our application:
The first thing I did is create separate folders for different modules. You can see that there is a book-management folder, another folder for the logger, and similar to that user-management. This way each module is focused and easy to locate and manage.
Each folder can have sub-folders and so on. Also, notice the index.js file at the folder level, this will serve as an API for the module.
Then, in app.js, we can reference the modules by requiring them and you can see that it works as expected. Notice how we can reference user.js by requiring it.
Now, let’s update our code:
Then we have following code in the corresponding index.js file:
So, now we have index.js acting as an API for the module. Let’s use it in app.js as follows:
And we can see that our application is working as expected. I went ahead and changed the user.js to follow the same constructor pattern of book.js and you can also try this as an exercise.
Here, is how our code looks after refactoring user.js part:
Our application is very basic and in this post, we started setting up the foundation by learning some of the basics of Node.js dependency management and some common ways of setting up your project structure.
My idea is to extend this learning closer to a real-world project and add more features and functionality to it gradually. I will try to write more in coming days on this topic. Let me know if you have some comments or questions. You can get the code from this Git Repo. Till next time, Happy Coding!