By Md. Sabuj Sarker | 5/11/2018 | General |Beginners

Node.js Backend Development - Creating Custom Modules

Node.js Backend Development - Creating Custom Modules

In the previous article we learned how to serve HTML files from the disk or file systems. In doing so we started to make our code larger. It started getting overlapped with callbacks and we may fall into the callback hell really soon. We need to separate code really soon before we mess up the whole system. Think about Node.js itself, it separates responsibilities into different modules. If it did not do so, it could not make a large system like Node.js. We also need to separate things to keep things clean. We need to create our own modules to separate our concerns.

Create or choose a directory where you want to keep your JavaScript files for this article. You can also clone the Github repository Learn Node.js With Sabuj. From the very first article you have seen that we are putting article specific code in separate git branches. Code for this article can be found in the branch called 003_writing_custom_modules. Create a file called main.js where we will keep our startup code for our application. Also create a directory named html and move home.html into it to keep everything separated. Also, crate another directory called custom_modules where we will put modules created by us. In this directory create a file named responder.js. This file will host code that will be responsible for sending response to the user agents. The main.js will just be used as a startup and controller script.

Before we proceed we need to know about the structure of the modules and how they work. A module is (usually) a pure JavaScript file like other JavaScript files in our projects. So, we can require() any JavaScript file. But requiring a file is not enough, we also need to tell Node.js which functions, objects, variables, etc. will be available after requiring. When we require() a JavaScript file, an objects called exports is made available to that script. So, whatever we want to make available after requiring must be attached to exports.

Let's say that we have a function called serveRequests() inside responder.js that will handle all the requests. We will need to write code like below for making it available after requiring.

responder.js

exports.serveRequests = function(request, response){
   // processing code here
};

Now, let's populate responder.js with the code we wrote previously.

responder.js

exports.serveRequests = function(request, response){
   fs.readFile('../html/home.html', function (error, file_data){
       if (error){
           response.writeHead(500, 
               {
                   'Content-Type': 'text/html'
               }
           );
           response.end("<b>Something Went Terribly Wrong</b>");    
       }else{
           response.writeHead(200, 
               {
                   'Content-Type': 'text/html'
               }
           );
           response.end(file_data);
       } 
   });
};

Notice that we have changed the HTML file path to html/home.html according to our new project structure. But wait, we will have to require fs, as requiring it in main.js will not make it available in this module.

var fs = require('fs');

exports.serveRequests = function(request, response){
   fs.readFile('../html/home.html', function (error, file_data){
       if (error){
           response.writeHead(500, 
               {
                   'Content-Type': 'text/html'
               }
           );
           response.end("<b>Something Went Terribly Wrong</b>");    
       }else{
           response.writeHead(200, 
               {
                   'Content-Type': 'text/html'
               }
           );
           response.end(file_data);
       } 
   });
};

Now, we want to use this function from main.js.

main.js

var http = require('http');
var responder = require('./custom_modules/responder');

http.createServer(responder.serveRequests)
   .listen(5000);

Built in modules can be imported/required without specifying their full path—referring to their name is all we need. But for custom modules we will have to specify the path to the module file. In this script we have told Node.js that the responder module lives in a directory named custom_modules inside the parent directory of the current script. So, we ended up writing require('./custom_modules/responder').

Now, fire up the command line, run the main.js file, go to the browser to see the same result as we have seen in our previous article. Everything is working as before, but our code is more organized and manageable now than ever before.

When we start developing our applications, we often start small and grow big gradually. Most of the problems take place when we start to grow big but do not separate different concerns to different modules. Think about Node.js itself, it is a collection of different C/C++ projects/libraries and also libraries of its own. It could not come so far if it were not modular, if it did not separate concerns into different files/modules/libraries. So, when you start creating an application, do not wait for it to get large. You will get lost when it will grow large. Make it modular before anything goes out of control.

You should practice all the code by yourself instead of just copying and pasting. If you ever need the all the final code, go to the Github repository mentioned earlier. Keep practicing by writing backend web applications with Node.js and keep your eyes open for new articles on this blog.

 

Previous article: reading and serving files

Next article: working with resources

 

About the Author

My name is Md. Sabuj Sarker. I am a Software Engineer, Trainer and Writer. I have over 10 years of experience in software development, web design and development, training, writing and some other cool stuff including few years of experience in mobile application development. I am also an open source contributor. Visit my github repository with username SabujXi.

By Md. Sabuj Sarker | 5/11/2018 | General

{{CommentsModel.TotalCount}} Comments

Your Comment

{{CommentsModel.Message}}

Recent Stories

Top DiscoverSDK Experts

User photo
3355
Ashton Torrence
Web and Windows developer
GUI | Web and 11 more
View Profile
User photo
3220
Mendy Bennett
Experienced with Ad network & Ad servers.
Mobile | Ad Networks and 1 more
View Profile
User photo
3060
Karen Fitzgerald
7 years in Cross-Platform development.
Mobile | Cross Platform Frameworks
View Profile
Show All
X

Compare Products

Select up to three two products to compare by clicking on the compare icon () of each product.

{{compareToolModel.Error}}

Now comparing:

{{product.ProductName | createSubstring:25}} X
Compare Now