DEV Community

Ingo Steinke
Ingo Steinke

Posted on • Updated on

Upgrading and refactoring a slightly outdated web project

Having neglected to maintain my personal portfolio website project for a while, it proves that there can be technical debt even in a very small project.

Technical Debt in a Mini-Project

Creating a fast and beautiful portfolio website in 2021, using PostCSS and eleventy seemed a little bit over the top. But I wanted to try out and use those technologies in an actual project instead of an unrealistic demo.

While it's only a single static page, there are two different language versions using the same style and markup, and I thought that I might extend some parts of the content, like the short project teaser tiles, to add more detailed sub-pages in the future.

Breaking Changes without a Benefit?

In a simple scenario like that, or even in a large project, when we only use a small part of all available features, software updates might bring no specific benefit at all, but risk breaking something that used to be working flawlessly.

Even without the announced major updates, my build process stopped working, so for doing some important fixes recently, I had to cheat and edit the source template and translations and also the output HTML files in both languages that should have been generated automatically.

As I found out later when adding other content updates, I must have pasted invalid characters into a configuration file and failed to find the reason that seemed obvious when taking my time to check properly.

Software Rot

As time goes by, "software rot" is only getting worse. And time will go by. It has been about half a year since I started writing this blog post, and I still hadn't found time for refactoring and updates.

But going back in time, here are some breaking changes introduced by an update of postcss-cli only a few months after I finished my project:

Screenshot: breaking changes introduced by postcss-cli 9.0

Apart from requiring a newer node version (v12+), they enforced a mandatory syntax to fix a bug, so I must make sure to "specify full file path, including .js extension, when loading local plugins with --use.

Trying to turn the problem into a challenge, I thought that I should take more time to check the changelog of any third party software that I use, and make sure that my code is tested properly. And, of course, I should question the perceived "because of nothing" and find out what possible improvements I might have been missing apart from unrelated bugfixes, and actually use new features. At least, learning has been one of the reasons to use that software in the first place.

So, hopefully, I will soon be able to blog about some super useful features of eleventy 2.0 that I haven't been aware of so far.

Improving Test Coverage before anything else

As I learned on several occasions, like the Never Code Alone Refactoring Conference, test-driven development (TDD) can ensure that we always have enough test coverage to refactor our applications without risking to break anything, provided that we do everything right from the start and go beyond 100% test coverage and prioritize testable clean code.

Although I think that we should take clean code with a grain of salt rather than following a gamified system of colorful paths and badges, I understand and respect the intention behind Clean Code and Software Craftsmanship, as it can help to prevent errors and technical debt from the start.

Google image search including the famous cartoon about the number of WTFs per minute

A more pragmatic and less pathetic approach, also not to be taken too seriously, is "the number of WTFs per minute" as a measure of code quality, which is also credited to originate from "Uncle Bob" Martin's book.

But, to be honest, as a notorious advocate of quirky web languages and a pragmatic hands-on approach at the intersection of programming and creative work, you wouldn't expect clean code and perfect test coverage in any of my past projects.

Strategies for Clean(er) Code Web Projects

There are some conceptual requirements to clean code that I always found hard to achieve in a traditional web project, but that's one more reason to use tools like static site generators and follow design patterns like Atomic Design, (A)BEM CSS, and a modular file structure.

Although I didn't follow these principles consistently on a technical level, they are inherent in the design. I can restructure the code to reflect the original modular intention and rename the CSS classes accordingly.

Screenshot of the Atomic Design website by Brad Frost

Hands-On Legacy Code Clean-Up

Admitting that my own project, while not legacy code in a technical sense, needs refactoring and improvement, I decided to add more tests before proceeding with anything else. A lot of tests, or at least enough to make sure I won't accidentally break anything important by refactoring.

I already started to improve test coverage in the past, and I was lucky to find out that screenshot testing has become easy to implement with behavior-driven test frameworks like CodeceptJS.

My Development Road Map

So I opened the most related issue in my GitHub repository. I had already planned to refactor my CSS when I first wrote, and there was a pending issue opened (by me) about a year ago.

Although nobody else has been working on my portfolio website so far, I still use git, branches, and issues just like I would when working for and together with others.

I changed the title to "upgrade tools and refactor CSS after snapshot testing", added some more checkboxes to track the progress of my upcoming work, and a run-on-sentence trying to summarize the requirements and their motivations like this:

As the maintainer of my own website, I want to keep the tools up to date and improve maintainability.

Following up with what would become the base of this blog post:

After not working on the site for a while, many tools have become outdated. Also, the codebase does not meet my current coding preferences anymore. Style sheets seem too chaotic, markup and content are mixed in a redundant way without leveraging modular possibilities of the static site generation system. And that system has seen two major upgrades meanwhile. While my site still runs on eleventy 0.x, there is a stable 2.0 release available.

None of those overdue changes should be done before increasing test coverage, including screenshot tests and possibly doing cross-browser end-to-end tests and audits.

My current checklist starts with "improve test coverage". You can see the rest on GitHub (refactor CSS after snapshot testing).

Keeping Side Projects Workable

Although my website is still up to date and usable, the projects and its code base have become another of my unfinished work-in-progress projects, much like learning Symfony/Shopware development and my rudimentary side project to build a reading list web app with Node, Preact, and Tailwind.

Often there won't be any progress over a very long time, as there is always something more important or urgent to do before proceeding with my ambitious clean-up and refactoring.

When I find time for my website, I mostly use it to update content or add a new feature (like trying out how to advance into the new CSS Level 4 color space).

But blog posts like this one, but also some amount of professional approach, helped me to follow up with projects that I started years ago.

Conclusion: Recording is Rewarding

So, apart from testing and a more modular project setup, this is my advice for fellow developers starting personal side projects:

Use documentation and project management tools for your side projects! That other developer struggling to make sense of your code is your future self, reading code, commits, and documentation, trying to remember where the project was intended to go and how to get there finally.

Documenting our decisions, intentions, and open issues, is like saving the state of a computer game or putting a bookmark in a novel and scribbling some notes about the main characters and key events if you only find time for reading occasionally. Our side projects are like books that we crave to finish one day, hopefully not having to restart at page one due to our faulty memory.

Top comments (0)