Refactoring: Enhancing Code for Better Maintainability
Tags: webdev, github, programming, javascript
Published: 2023-10-14 04:57:44

Code refactoring is a critical process in software development that involves restructuring existing code to improve its readability, maintainability, and efficiency without changing its external behavior. It is like renovating a house to make it more comfortable and functional without altering its appearance. In this blog post, I will take a journey through the process of refactoring a Node.js application and explore the various steps and considerations involved.

## The Starting Point
To begin refactoring journey, I have a Node.js [TextToHtml](https://github.com/bhavik001/TxtToHTML.git) command line tool that converts `text` files (both `.txt` and `.md`) into `HTML` files. It's functional but could benefit from some improvements to make it cleaner and more maintainable.

## Step 1: Removing Global Variables
I began my refactoring approach by getting rid of global variables. Global variables can cause name conflicts, reduce the modularity of the code, and make it harder to read. In my case, I had a global variable for the version number obtained from `package.json`. I replaced it with a function, `getVersion()`, which reads the version from the `package.json` file. This change improved code readability and reduced the risk of naming conflicts.

```bash
function getVersion() {
  const packageJson = JSON.parse(fs.readFileSync("package.json", "utf-8"));
  return packageJson.version;
}
```
**Commit Message:** `Refactor: Removed global version variable`

## Step 2: Refactoring the `clearOutputDir` Function
The next area of improvement was the `clearOutputDir` function. This function was responsible for clearing the output directory, but its implementation could be more concise. I replaced it with the more efficient `fs.rmSync` function to remove the directory and its contents recursively. This change not only made the code cleaner but also improved its performance.

```bash
function clearOutputDir(outputDirectory) {
  if (fs.existsSync(outputDirectory)) {
    fs.rmSync(outputDirectory, { recursive: true, force: true });
  }
}

```
**Commit Message:** `Refactor the clearOutputDir function to make it more concise`

## Step 3: Improved Variable Naming

In this step, I focused on improving the naming of variables throughout the codebase. Descriptive variable names help developers understand the purpose and context of each variable, making the code more self-documenting.

For example, I updated variable names like `inputPath`, `outputDir`, and `inputFileContent` to be more descriptive of their roles and improved code readability.
**Commit Message:** `Improve variable naming to more descriptive names`

## The Interactive Git Rebase
Each of these separate refactoring stages resulted in a number of distinct commits. I used an interactive Git rebase to provide a tidy and structured commit history. This process allowed us to squash the individual refactoring commits into a single commit.

To do this, I used the `git rebase main -i` command and marked the commits I wanted to squash. I also amended the commit message to provide a more informative summary of the changes made during the refactoring process.

## Bugs and Challenges
During the refactoring process, I encountered a few challenges, but careful testing and well-structured refactoring steps helped avoid introducing new bugs. The step-by-step approach allowed us to verify that each change maintained the functionality of the application