Refactoring & Rebasing
Published: 2021-10-15 01:31:33

## Overview

This week, my main focus is to clean up and refactor my static site generator. With so many people working on the project for the past few weeks, it isn't strange to see duplicated logic and unnecessary variables. And as the project grows, improving the quality of the code will not only make it more readable but also allow for better error handling and maintainability.

## Refactoring

Here is my list of what to change in the existing codebase:

* Moving all the source files into a `/src` directory
* Changing the file name to use kebab-case and updating the imports in the entry file
* Reversing the logic for checking file extensions
* Splitting the tasks in `generateHTMLFile()` to smaller functions

### 1. Moving all the source files into a `/src` directory

Currently, my file structure looks like this:

```
root-dir
|- mini-ssg.js
|- utils
   |- generateHTML.js
   |- processInput.js
   |- processJSON.js 
|- package.json
|- README.md
```

With this file structure, it will become harder to navigate as the project gets larger. Therefore, one of the things you can do to make your coding experience easier is separate the sources files into a different directory and reserve the root directory for metadata (e.g., `package.json`, linting, `config` files, `README.md`, etc.) 

The result should look something like this:

```
root-dir
|-src
  |- mini-ssg.js
  |- utils
     |- generateHTML.js
     |- processInput.js
     |- processJSON.js 
|- package.json
|- README.md
```

### 2. Changing the file name to use kebab-case and updating the imports in the entry file

Before, I was using camel-case for file names. However, I learned that not all file systems were case-sensitive. As such, `fileName1` and `filename1` might or might not be the same file. Changing the naming into kebab-case (e.g, `file-name`) resolves that issue.

### 3. Reversing the logic for checking file extensions

I was having a bit of trouble looking for what to refactor. As such, asking for help on Slack gave me a lot of insight into what can be improved. One of the recommendations I saw was to revert the logic to check for the file extensions.

To be specific, here is the old one:  

```js
if (path.extname(inputPath) === ".json") {
    // main logic
}

console.log("File extension must be '.json'.");
return process.exit(1);
```

While it is okay to keep the existing code, reversing the checking logic would help save me from indenting an `if` statement to run the main logic. As such, I modified the function into:

```js
if (path.extname(inputPath) !== ".json") {
    console.log("File extension must be '.json'.");
    return process.exit(1);
    
}

// main logic
```

### 4. Splitting the tasks in `generateHTMLFile()` to smaller functions

When refactoring, it is usually best to break functions into smaller chunks. Not only does it allow the function to be easier to read and understand, but you also have more control over what each of them does, which makes finding errors simpler.

I realized that my `generateHTMLFile()` function is getting a bit too big, and is doing too many things at once:

```js
async function generateHTMLFile(...parameters) {
  // a big group of code to generate the HTML body

  // logic to create file and write HTML content   
}
```

The logic to generate the HTML body can be extracted into its own function and `generateHTMLFile()` will use the function to get the result:

```js
async function generateHTMLFile() {
  const htmlBody = generateHTMLBody()

  // logic to create file and write HTML content   
}

function generateHTMLBody() {
  // a big group of code to generate the HTML body
}
```

With this approach, in addition to reducing the number of tasks that `generateHTMLFile()` does, I also surprisingly avoid using the global variable storing the HTML body that I had before.

## Rebasing

`git rebase` and `git commit —amend` came in handy during the refactoring because they allowed me to patch up and re-organize my commit. The option to combine many commits into a single commit and change the message of the most recent commit has cleaned up my git history, making the top-level message of each git commit more relevant.

## Additional links
My project 💻: [mini-ssg](https://github.com/mqnguyen5/mini-ssg)
Rebase commit 📝: [f42e5b6](https://github.com/mqnguyen5/mini-ssg/commit/f42e5b673803399803db137ffac99826f6114176)