Category Archives: טכנולוגיה

Replacing a live front-end legacy code – The bottom to top migration strategy

This article is written about work done in 2016 – and the technoloigies mentioned match the time:

Here’s the deal – A company has an existing product with outdated technology, an old legacy code which is unmaintainable and unextendable, essentially, written with old technology. The company in question understands that it’s time to move forward, catching up with the present day and time.

Unlike the usual method of rewriting an entire product from scratch (top to bottom), there is a better way. This includes building a new front-end feature and immediately using it within the old legacy product. This methodology works even when the technologies are light years away from each other.

I used to work for a company like that. Before I started working there, their initial starting point included an old product which was an auto-generated HTML code out of a java backend, also known as “Automagically generated JS, CSS, and HTML”. This happens to be a front-end developer’s true horror.

This company decided to rewrite its product from scratch, with all new technology (Javascript and a Python API). They recruited developers, product specialists, used the best resources, and meeting hours. This was the first time that this company had a big front-end project ahead of them.

During the following year, they had an old legacy product that was live. It was making money but had minimum resources for maintenance, and no new features whatsoever.

On the other side of the development department, a new pile of fresh code and architecture was just beginning to be written. Unfortunately, it piled up and laid there without anyone knowing about the product or its users. The feature set wasn’t that big, but because this product was supposed to replace an already live product, no one could cut the scope of its features.

After more than a year, the freshly written code and architecture failed to reach its deadline, and there was no end in the horizon.

The project was canceled.

So there we were, with a year’s worth of development time and fresh code, but none that was usable. We had a product that was not maintainable and a business that needed to keep working and growing.

We all wondered, how could we all solve this horrible problem? What would have been the best way to make up for this lost project before us? How could we revive our motivation and bring back trust to the front-end department in the company?

I was called on to find a solution – and thankfully, did. The solution focused on the business. For a developer that always wanted the cutting-edge technology to be written from scratch – it was a difficult solution to understand, at the beginning.

The idea  was to reach goals in a better way:

The solution included giving the company the possibility to maintain and add features to its old applications. And, in such a way that also took the company forward in the direction of having a full new front-end application as needed. The solution enabled us to transparently transition from an old product to a new and cutting-edge front-end product.

Unlike the original method that was used which included rewriting the whole product from scratch (i.e. from top to bottom), the new method  was from bottom to top. I determined that we could build a new front-end feature and immediately use it, and we could make a profit and learn from it.

This also enabled us to stop at any point, and to shift resources at any time, without any loss. This was because every new feature was already in production, and embedded in the old application, but separated and detached from it.

This solution undertook important calculations and measurements:  

  1. Time / Resources
  2. Risks
  3. Scope
  4. Technical limitations

Technical Problem:

In all actuality, the legacy product was very limited from a UI perspective. We were bounded only by the UI elements and functionality that it provides. And, it is not a front-end friendly framework at all – it is a closed product.

Even worst –  it was mixed in with badly implemented JS code, on top of old product, which “helped” overcome the above problem in the past, this layer can be called: the hacks layer.

It was unscalable for code/feature extension, and since each update is global, it can easily break style and functionality.

We must keep developing the money-maker products, and we cannot merely rewrite it.

When addressing a migration from an old technology to another, we developers always think about a total new re-write. But if you are able, technically, to isolate your new code, components, and UI elements – you can do the re-write in a much more efficient way.

Infrastructure preparation:

On top of all feature requests, we must implement a few front-end infrastructure features:

The idea of this preparation job is to offer a set of front-end tools for easier maintenance, deployment, and development:

  • E2E tests (wooha, Selenium)
  • SASS compiling
  • Minifier / Concatenator
  • Angular
  • Bower

Now to the real work:

JS

We chose Angular.

Most importantly, the new code must be encapsulated, and most importantly, we must not rely on the DOM.

We found Angular the most encapsulated framework, allowing us to separate our JS code and HTML from the old container.

Each component must contain an angular view and have the ng-application root. We don’t want Angular to waste resources on listening to the whole DOM (and conflicts with the legacy lib). We encapsulated the page too small Angular apps.

CSS

Style separation: The Style lib

The style we came up with was the most complicated part.

CSS is inherited. There is no easy way to encapsulate an element from a CSS rule that applies to this selector (There is one way, but it is not supported by any IE, and we could use other tricks, that looked hacky).

So, we have an old framework, with a big pile of CSS, and with various rules that select tags, classes, states, and most importantly – deep rules, such as:

body form label input [type-text]{}

There is no way to write generic rules that can predict and override them.

Also – When we write a new feature, we cannot determine what overrides what. There is an option to check in the development tools, but this is a very long process, especially for each rule.

The solution was a separate UI lib. We generated two CSS files: The old Lib.css and the newLib.css.*
On our portal, we included both files.
On a separate static HTML page, we included only the newLib.css file.

When a new feature is being built, or an existing feature is being rebuilt, we must first build it inside the static HTML. Thus, creating it’s CSS rules in a clean, isolated environment.

At this stage, we know that the independent style we included on the page will work when we remove the oldLib.css file.

As for the rules from oldLib.css that are overriding the newly created rules (some !important or deep nesting rules from the legacy code that we cannot remove), they were minimal in numbers and got their special overridden section at the end of newLib.css

Once the oldLib.css file is removed, we can then remove the sections. We will then have an immediate working product, with minimum need to adjust and fix.

Results:

As for the time spent writing these lines, many of its features were overridden, and many new features were built, all with a new front-end code. They are all live, which immediately allows the company to earn money from the invested time they spent.

In this case, the old legacy product is maintained again, it is also extendable, and one day, it will get rid of the old code easily because of this separation.

What we created allows us to change resources without any problem whatsoever. No waiting on code that will never see the light of day or make any money.

And, on the developer side, we are able to do cutting-edge technology, using the tools that we would have used in a complete rewrite project. But, now we have an even better, harder, and more complicated task. This challenges us more and helps us to find solutions that other developers who use frameworks out of the box don’t need to deal with. It forces us to need a better developer, better learning processes, and a great backup and belief from the company management that this is achievable.

The above solution gives us the possibility to maintain and add features in such a way that will also take us forward in the direction of having a full new front-end product, in its old automagically generated front-end. It also enables us to have a transparent transition of the old product, to a new cutting-edge front-end product, which is miraculous.

* not the real names of the files

The github code review problem / Product before code

The remote / GitHub code review problem:

A part of any developer’s workflow is the code review, the main tool these days to do that in a team is the great feature of the code review with GitHub. (Usually, with the pull request).
The feature is amazing. Code comparison view, line by line comments, tagging, mentioning – it’s like fucking developer’s social media. It’s great, but we have lost an important part in this new workflow tool – we lost the product.

We have three well-known methods to review a code:

  1. Not to review a code.

Next:

2.   The pair programming:
Our code is great, and we know how it can be even better, when having a second eye on it in a pair programming session. It is really the best way. Some love it, some hate it (I personally, know that it will achieve the best results, but most of the time still prefer to fire keyboard signals with my headphones, in my “zone”).
It is also known that it’s something that not all companies or developers will accept. Most of them won’t. It’s costing more money on dev-time and does not save the same 50% of fewer bugs.
It is also not comfortable. You need to sync time. Sometimes somebody is sick. Sometimes you’re better alone. It’s perfectly fine. I am sure that most of the beautiful pieces of code in the world were written first by a lonely developer. (I hope that he/she was sitting in an airplane, avoiding screaming children, noises with earphones full with Volbeat music, which is exactly what I am doing now).

3.  The code review:
The middle way, between the pair programming and the no review, is the good old code review.
In this way, you don’t waste money on double dev-time. You get your “zone”, but you still get a second eye on your code.
You both look at the branch / PR, but also look at the feature, as it is already open in the developer’s browser. You try it, and play with it to understand what the code should do. You have immediate communication with the developer so you can ask/react to the feature and get a reaction back immediately.
Reviewing a code without seeing the feature/bugfix at work, is just testing a car only by its blueprint. No practical test before passing it to QA or even – pushing toward an acceptance test.

Now we got lazy. We check the pull request, we don’t sit together and explain. It is rare for people to actually pull the branch to their computer. They don’t need to anymore, so they won’t try the feature. This is how we lose the best power of the review – deploying a great, working feature. A beautiful code is great, but worth nothing without a working product.
I see this change and how it hurt us. Open source projects and private projects, getting more and more bugs that would never happen with a real feature review. It costs money, and it’s a downgrade to a dev-process that advanced so well in the last years. We have such great tools – don’t let them lead the human brain. They are just tools.

I say – review, with your locale tool. Try the feature, or a feature that uses this piece of code.
We should not become just coders, masters of beautiful abstractions and a code that looks like a poem. We should also never forget the reason we write it – the product is paying our salary – the final result of our masterpiece.

CSS nesting html elements limitation – ~~useless info

It appears that different browsers are limiting the number of nesting elements in an HTML page that a single CSS rule can use.
It looks like each browser has its very own different limitation.

While testing performance I tried to nest big amount of divs, 1000 of them. I gave each a following number (yeah, produced with javascript i++ and copied the result from the devtool), and tried to apply a single rule to it.

div .div998 { color: blue;}

It didn’t work. I tried to debug the HTML, thinking that I might have some problems with not closing elements or a wrong class, then began to change the class in the CSS rule to a higher container.I reached to the point from which the CSS won’t apply, the browser limitation.

Look at the following jsfiddler (looks like this is too heavy for embedding, so I removed the embedded code, please use the url).
Please leave a clean playground:

http://jsfiddle.net/Lhd8ny8w/5/

You can play with the class number to find your browser’s limitation.

With chrome (chrome OS version 41.0.2272.41) the limit is 509. With my Firefox 30 the limit is 198. If you change the rule to 510 or higher, you will see that the rule won’t apply. change it back to a lower class, and it will apply.

I am afraid to check IE’s limitation.

You can play with that on different browsers, there is no standard defined that I could find in the specs, and each browser has its very different limitation.

As its a bad use to have so many nested elements, it is still good to know, since lots of markup today is generated aoutomagically, by js or magic backend and sometimes we won’t notice that its so big, and try to understand, frustrating, why our style rules won’t work.