Refactor: How I Improve My Barrierless Project
Vinh Nhan
Posted on October 12, 2024
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
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:
-
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"
-
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"
-
Switching from
require
toimport
Since I'm working in a modern JavaScript environment with ES6 modules, I replacedrequire
statements withimport
statements foros
andfs
insrc/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"
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:
- Refactor a section of the code.
- Test the functionality manually.
- 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
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
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
Finally, I pushed the updated main
branch to GitHub:
git push origin main
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.
Posted on October 12, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.