Refactor: How I Improve My Barrierless Project

vinhyan

Vinh Nhan

Posted on October 12, 2024

Refactor: How I Improve My Barrierless Project

Hello! 👋

After reading through the refactoring walk-through example in class, it was time to apply those lessons to my own project: Barrierless. The goal was to improve the code’s structure, readability, modularity, and maintainability. Refactoring helps set the stage for long-term success by making code easier to read, debug, and expand, especially with automated testing on the horizon. Here’s how my refactoring journey went.

Step 1: Branching Out

The first step was creating a dedicated refactoring branch from my main branch:

git checkout -b refactoring
Enter fullscreen mode Exit fullscreen mode

This ensured that any mistakes I made during the refactoring process wouldn’t affect the stability of my main branch.

Step 2: Finding the Issues

I reviewed my code and identified three key areas that needed improvement:

  1. Separate Concerns: Modularizing My Code Initially, my code handled command-line arguments, file parsing, AI management, and output all in the same space in index.js, making it harder to manage. I decided to separate these responsibilities into different modules:
  • One module for command-line arguments and options: /src/cli.
  • Two modules for input and output file handling: /src/input& /src/output.
  • A separate one for AI translation management /src/translation.

This refactoring increased the modularity and maintainability of the code, allowing each part to be more focused and reusable. At the same time, I also added a logic to validate the language option specified by the user, based on the IOS639-1 and 3 standard. Then, I created the first commit for this refactor after testing the separation:

   git commit -m "modularize code into input, output, translation, cli. Add IOS639-1 and 3 language standard validation"
Enter fullscreen mode Exit fullscreen mode
  1. Eliminate Global Variables I noticed that some global variables were used in index.js, which could lead to unexpected behavior as the project scales. To fix this, I encapsulated the necessary variables within the respective modules, ensuring that no global variables were needed in index.js. This enhanced the code's reliability and reduced the risk of bugs in that specific file:
   git commit -m "remove global variables in index.js"
Enter fullscreen mode Exit fullscreen mode
  1. Switching from require to import Since I'm working in a modern JavaScript environment with ES6 modules, I replaced require statements with import statements for os and fs in src/utils.js. This not only makes the code more modern but also aligns it with the rest of the current code and the latest JavaScript standards:
   git commit -m "changed 'require' to 'import' for os and fs"
Enter fullscreen mode Exit fullscreen mode

Step 3: Commit and Test

After each refactor, I made sure to thoroughly test the code to ensure I hadn’t introduced any breaking changes. My workflow looked like this:

  1. Refactor a section of the code.
  2. Test the functionality manually.
  3. Commit the changes.

I was careful to follow the rule of one problem, one commit, which kept each commit focused and easy to follow.

Step 4: Interactive Git Rebase

Once I was happy with the refactoring, I performed an interactive rebase to squash all of the refactoring commits into a single commit. This makes the history cleaner and easier to understand. The process was straightforward:

git rebase -i 
Enter fullscreen mode Exit fullscreen mode

I marked the commits I wanted to squash, and when everything was ready, I used an amended commit message to add the bullet points to the current commit messages:

git commit --amend
Enter fullscreen mode Exit fullscreen mode

Step 5: Merging the Refactor Branch

With the rebase completed and all tests passing, I merged the refactor branch back into main:

git checkout main
git merge --ff-only refactoring
Enter fullscreen mode Exit fullscreen mode

Finally, I pushed the updated main branch to GitHub:

git push origin main
Enter fullscreen mode Exit fullscreen mode

Lessons Learned

  • Interactive Rebase: This was a great tool to clean up my commit history. It was my first time using it for squashing commits, and it made the refactoring process feel polished.
  • Modularization: Breaking up the responsibilities into separate modules made the code easier to read and reason about. It also made debugging and testing more focused.
  • No Global Variables: By removing global variables, the code is less prone to hard-to-find bugs and is better organized.
  • Switching to ES6 Imports: This step brought my project up to modern standards, ensuring better compatibility with future projects.

I didn’t encounter any significant bugs during the refactor, but I did notice that some parts of my code were more fragile than I had realized. Refactoring exposed those areas, making it easier to address them in the future. The overall process was smooth, and the improved organization will make future changes easier to implement.

💖 💪 🙅 🚩
vinhyan
Vinh Nhan

Posted on October 12, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related