Building Custom Modules
Node.js is a powerful platform for building scalable and efficient applications. One of its core strengths lies in its modular architecture, which allows developers to create and use custom modules. By leveraging custom modules, you can organize your code better, enhance reusability, and maintain a cleaner codebase.
Before diving into the hands-on practice of building custom modules, it’s essential to understand why they are necessary and how they can benefit your Node.js projects. If you haven’t already, we highly recommend reading our previous article, “Why Do We Need Custom Modules?”. This foundational piece will provide you with the context and motivation for using custom modules, setting the stage for the practical exercises we’ll explore in this article.
In “Hands-On Node.js: Building Custom Modules,” we will guide you through a series of exercises designed to help you create, export, and import custom modules. By the end of this article, you’ll have a solid grasp of how to build your own modules, integrate them into your projects, and take full advantage of Node.js’s modular capabilities. Let’s get started!
Question : Create a custom module named httpServer.js that exports a function to start a basic HTTP server. The server should respond with a simple HTML page for any request. In a startServer.js file, import the httpServer module and use it to start the server. |
Solution : First create httpServer.js file, and write the below code :
// httpServer.js const http = require('http'); function startServer() { const server = http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'text/html' }); res.end('<html><body><h1>Hello, Study Trigger!</h1></body></html>'); }); server.listen(3000, () => { console.log('Server is running on http://localhost:3000'); }); } module.exports = startServer; After that, create a startServer.js file and write the below code : // startServer.js const startServer = require('./httpServer'); startServer(); |
Question : Develop a module named middleware.js that exports a middleware function for logging request details (method, URL, and timestamp) in an Express.js application. Create a server.js file that sets up a basic Express server and uses the custom middleware to log details of incoming requests. |
Solution : Create a middleware.js file and write the following code
// middleware.js function logRequestDetails(req, res, next) { const method = req.method; const url = req.url; const timestamp = new Date().toISOString(); console.log(`[${timestamp}] ${method} ${url}`); next(); } module.exports = logRequestDetails; Now, create a server.js file and call the above method: // server.js const express = require('express'); const logRequestDetails = require('./middleware'); const app = express(); // Use the custom middleware app.use(logRequestDetails); app.get('/', (req, res) => { res.send('Hello, World!'); }); app.listen(3000, () => { console.log('Server is running on http://localhost:3000'); }); |
Question: Write a module named dbConnect.js that exports a function to connect to a MongoDB database using Mongoose. The function should log a message on successful connection or log an error on failure. In a app.js file, import the dbConnect module and call the connection function to connect to a MongoDB database. |
Solution : Firstly, install mongo db using command “npm install mongoose”
Now create dbConnect.js and write the below code : // dbConnect.js const mongoose = require('mongoose'); function connectToDatabase() { const uri = 'mongodb://localhost:27017/mydatabase'; // Replace with your MongoDB URI mongoose.connect(uri, { useNewUrlParser: true, useUnifiedTopology: true }) .then(() => { console.log('Successfully connected to the database'); }) .catch((error) => { console.error('Error connecting to the database', error); }); } module.exports = connectToDatabase; Create app.js file and write : // app.js const connectToDatabase = require('./dbConnect'); // Connect to the MongoDB database connectToDatabase(); |
Question : Create a module named emailSender.js that exports a function to send emails using a popular Node.js email package like nodemailer. The function should accept email details (to, subject, text). Write a sendEmail.js file that imports the emailSender module and sends a test email to a specified address. |
Solution : Step 1 Install nodemailer using “npm install nodemailer”. Create a file called emailSender.js
// emailSender.js const nodemailer = require('nodemailer'); function sendEmail(to, subject, text) { // Create a transporter object using SMTP transport const transporter = nodemailer.createTransport({ service: 'gmail', auth: { user: 'your-email@gmail.com', pass: 'your-email-password' } }); // Define the email options const mailOptions = { from: 'your-email@gmail.com', to: to, subject: subject, text: text }; // Send the email transporter.sendMail(mailOptions, (error, info) => { if (error) { console.log('Error occurred: ', error); } else { console.log('Email sent: ', info.response); } }); } module.exports = sendEmail; Create sendemail.js file // sendEmail.js const sendEmail = require('./emailSender'); // Send a test email sendEmail('recipient@example.com', 'Test Email', 'This is a test email sent using Nodemailer.'); |
Question : Develop a module named fileUploader.js that exports a function to handle file uploads in an Express.js application using multer. The function should configure multer to save uploaded files to a specific directory. Create a uplaod.js file that sets up an Express server with an endpoint for file uploads, using the fileUploader module to handle the file upload.
Solution : First, install Multer if you haven’t already by using the command “npm install multer”. Create FileUploader.js file, and write // fileUploader.js const multer = require('multer'); const path = require('path'); // Set storage engine const storage = multer.diskStorage({ destination: './uploads/', filename: (req, file, cb) => { cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname)); } }); // Initialize upload const upload = multer({ storage: storage, limits: { fileSize: 1000000 }, // Limit file size to 1MB fileFilter: (req, file, cb) => { checkFileType(file, cb); } }).single('myFile'); // Check file type function checkFileType(file, cb) { const filetypes = /jpeg|jpg|png|gif/; const extname = filetypes.test(path.extname(file.originalname).toLowerCase()); const mimetype = filetypes.test(file.mimetype); if (mimetype && extname) { return cb(null, true); } else { cb('Error: Images Only!'); } } module.exports = upload; Then, create upload.js file : // upload.js const express = require('express'); const upload = require('./fileUploader'); const path = require('path'); const app = express(); // Set static folder app.use(express.static('./public')); // Upload endpoint app.post('/upload', (req, res) => { upload(req, res, (err) => { if (err) { res.status(400).send(err); } else { if (req.file == undefined) { res.status(400).send('No file selected!'); } else { res.send(`File uploaded: ${req.file.filename}`); } } }); }); app.listen(3000, () => { console.log('Server is running on http://localhost:3000'); }); |
Question : Write a module named customLogger.js that exports a logger with custom severity levels (info, debug, error, critical). Each log should include a timestamp and be written to a log file. In a testLogger.js file, use the customModule module to log messages at different severity levels and observe the outputs.
Solution : Install winston package by using command “npm install winston” Create a file called customLogger.js and write the below code: // customLogger.js const { createLogger, format, transports } = require('winston'); const { combine, timestamp, printf } = format; const path = require('path'); // Define custom log levels const customLevels = { levels: { info: 0, debug: 1, error: 2, critical: 3 }, colors: { info: 'blue', debug: 'green', error: 'red', critical: 'magenta' } }; // Define custom format const customFormat = printf(({ level, message, timestamp }) => { return `${timestamp} [${level.toUpperCase()}]: ${message}`; }); // Create logger const logger = createLogger({ levels: customLevels.levels, format: combine( timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), customFormat ), transports: [ new transports.File({ filename: path.join(__dirname, 'logs', 'app.log') }) ] }); module.exports = logger; Create testLogger.js file and write : // testLogger.js const logger = require('./customLogger'); // Log messages at different severity levels logger.info('This is an info message'); logger.debug('This is a debug message'); logger.error('This is an error message'); logger.critical('This is a critical message'); |