Three-pass Front End refactoring algorithm

Mikita Dusmikeev
6 min readAug 14, 2021

I came across a pretty large project written in React + Typescript. I poked around the code. Everything is awesome, containers, components, types are everywhere, linter is set up, styled-components, there is even a storybook and some react-query.

A project of a dream!

I start to do a simple task — some page to assemble from components.

I write in code But… and IDE offers me 16 Button components.

Geez…

Okay, I took out the component/Button from the components (p.s. it’s the only one there).

Next is Inp… well, you get the idea. 23 of these Inputs all over the project.

Okay then. I open storybook to copy everything from it. But there are only simple components, like buttons, H1, H3. And no components with the state — no form, no table with values.

The sky’s the limit for my happiness.

I keep digging further. Turns out that containers include not only containers (actually, I’ve always questioned this term, I prefer the word page or subpage/section), but also the components directly related to the page.

The classic story — not everything was taken out in reusable components and 4–5 large components were simply copied into different containers (container folders), where they are used.

I hope I’ve made the whole picture clear.

The moral of the foregoing is that behind cool and trendy technology there will not necessarily be convenient code (just kidding…)

I started to think what to do. Tasks keep coming in, and it’s not convenient for me to work.

One-week sprints with only me working in the project. Makes sense, it would be nice to fix it, but how to do it?

I have a sprint due every week.

Of course, the customer will be happy to have more control over the code after refactoring, but not at the cost of a sprint.

So I came up with the “Three-Pass Front End Refactoring Algorithm” (thanks, Knuth).

Here’s the plan:

1. Write out the main screw-ups in Jira/Asana/Trello/Linear/whatever!

2. Insert comments “// TODO:ID description” throughout the project (take the ID from step 1).

3. Make what’s written in TODO in your free time.

So what do you get?

You can arrange TODOs throughout the code in 2–3 days if you are already familiar with the project (in my case, I can easily find time for it during 1–2 sprints).

And TODO will help you with:

First of all, calmly explaining to the customer how many bugs there are in your code (use CTRL+SHIFT+F and look for // TODO:ID, then show them how many times this bug if found, for example 23 instances of the same thing).

Second of all, getting rid of the shitty code. You will see the TODO above the damn unfortunate place and you will choose whether to fix it right now or during the next sprint.

And I’m not even joking, a shitty code that says “TODO — fix” is magically not a shitty code anymore. It even has a special name, technical debt.

Let’s take a closer look.

Step 1.

I got these kinds of tasks in Linear (it’s like Jira):

In each subtask I have detailed what’s what. I don’t see much point in describing everything in detail here, it will still be different for each project.

Explanations that I think are necessary:

Add stories — means to add stories for a component to storybook.

Move components into components — the actual components (reusable) were in containers. They are supposed to be moved into components.

Step 2.

We got these cool styled-components (I hid the unnecessary).

In the same way, I added // TODO above components that need to be moved from containers to components.

And the same with all the other comment. I think you can see the whole picture yourself…

How not to get bogged down with copying TODO?

I decided to do everything in one pass through the project.

From the components folder to the containers folder.

I opened Linear and copied all the IDs.

I wrote them into the document, added descriptions.

Then pressed Windows + V and the clipboard opened (sorry for such poor quality — it closes when I try to take a screenshot, I had to take a picture with my phone).

And then I just went over all the components and containers, utilities and styles and pasted all the TODO comments from the same Windows + V clipboard.

Yes, I had to think about what things to move and where to move them.

But it turned out easy and didn’t take much time. In some places, I even used a global substitution (Ctrl + Shift + V).

For example, to replace

const Button =

with

// TODO: TFR-45:Button…
const Button =

Step 3.

Attentive readers may have noticed the difference in the entries.

Unlike other TODOs, TFR-44 and TFR-45 have a colon and some word after their ID. This word is the name of the components folder, where they should be moved.

You’re probably wondering why I added that.

Well, it’s simple. I decided to automate the moving of my 16 Buttons and 23 Inputs using node.js and simple regular expressions.

The concept is simple:

1. I move the entire piece from “// TODO ID…” to “};” to a specified folder in a file named “Folder(from)+ComponentName”.

That is, the entire styled-component with its repeated name and styles.

2. I import the moved component into the file, which is named after the export location of the component. And in the previous place I insert the import of the new component.

The description turned out pretty complicated, so I attach the picture below.

3. And then dealing with a bunch of new component files will be simple — I’ll check if there are similar ones, delete repeating pieces, make mixins, etc.

To make life easier, I wrote this script: https://github.com/DrBoria/component-mover

In my case, all repeating components were styled-components.

That is, they ended with “};”.

That’s why I apply a relevant regular expression.

If it doesn’t suit you — add your own, or just make a // TODO end comment at the end of the piece you want to take out, and you will have a regular expression from “// TODO ID…” to “// TODO end”.

Yes, it means a little more copy-pasting.

But you can start right away, without wasting time for preparing.

And most importantly — it can be done in 1 working day.

Do you have a free day in your sprint? Do you want to make your life easier?

Then you start a regular expression.

Refactor strictly one component (for example, the button).

And voila!

Now you know how to work with buttons in your project.

And the rest of the TODOs are waiting until a better day.

To summarize, let’s see what we can do with this algorithm:

  1. You and your customer are aware of the amount of technical debt in the project. It is absolutely measurable.
  2. It is much easier for you to understand how much time you will need to refactor each part of the project (perhaps it is easier for someone to understand how much time all of it needs).
  3. You have the ability to automate refactoring (both with the script above and with your self-written ones).

--

--