About external improvements

Do you know Outline?

Lately, I started using it to skip over so called soft paywalls. It works most of the times.

But today, unexpectedly, it resuscitated dead content too!

Look at the following snapshot of a passage in an interesting article about software architecture with microservices:

https://segment.com/blog/goodbye-microservices/

Look at how the second paragraph ends: “A sample payload looks like the following:” and how the next paragraph begins: “As events were consumed from the queue,“. Something is clearly missing. Where is the payload sample? Nowhere to be found.

Completely unrelated to that issue, I decided to open the page in outline, because I remembered I had seen it was possible to add annotations to transformed pages.

To open a page in Outline is extremely simple, just prefix its full URL with “https://outline.com/” and the service will present to you the transformed page at that URL.

What a surprise when I scrolled through the same passage and saw this:

https://outline.com/asskU

For some reason, Outline was able to resuscitate the dead content, but it got the section title wrong. (sigh, a minor drawback).

Do you know the Web Archive?

I researched a bit in its captures of the microservices article (almost 200, as of today) and found out that the payload content died between the 28th of March 2020 and the 23rd of April 2020, as yo can see from these captures:

28 March 2020

https://web.archive.org/web/20200328190530/https://segment.com/blog/goodbye-microservices/

23 April 2020

https://web.archive.org/web/20200423005607/https://segment.com/blog/goodbye-microservices/

But, wait a moment. Look at the section title in the capture of the 28th of March: “Why Microservices work worked”. Outline’s error seems so much minor now. So much so that the original page got it wrong too.

Do you know Hypothes.is?

I was going to end this article with a link to the Outline page with my worthy annotations, but it turns out that Outline URLs are broken, apparently. This page https://outline.com/asskU doesn’t work today.

However, the annotation service is provided by Hypothes.is. If you have Google Chrome, you can install their excellent browser extension, and navigate to the “official” Segment article to see my annotations, and add yours, if you like.

My annotation is here

Extract reusable code

While working at REDACTED-2, I reported the following issue.

The frontend files are scattered with contextual functions (declared in another’s closure). It is something totally common in small programs, but in large applications we try to limit its use as much as possible because they do not allow the code to be reused.

Some of the functions that at the time we understood to be reusable, we promoted them to Angular’s filters, thanks to the fact that filters are practically global, and can be called from the JS code. But Angular’s filters exist to be used from within HTML code, essentially to transform text to text.

It is difficult to calculate the amount of reusable code that we currently have embedded in the application. To deal with it, it is best to do it little by little over time, like occasional refactoring, when we find ourselves maintaining the corresponding code.

The idea is to group that reusable code within the utilities file or the utilities directory, organize it according to functionality, make it comply with our standards, deduplicate it, and add enough unit tests.

Group filters into utilities

There are currently more than 150 filters in the application. Each of these filters can be extracted from the file in which it is declared and added to the utilities file, which can then be injected wherever needed, as shown in the example of REDACTED.

Eliminate hacks of yesteryear

Ages ago it was done indiscriminately but now it is considered the result of inexperience: changing the prototype of a language class, such as String, Array, …

For example in REDACTED we define String.prototype.format = function …. There is already a whole functionality in utils._.template extensively documented. Also, I recently added utils.interpolate myself.

The task is to find the uses of .prototype in the entire application (about 1200 on January 31, 2019). Some will be about our classes: these are the correct ones. Others will be about JS classes: these are the ones to be patiently moved to utilities. This is really painstaking work.

Front End – Modernization Plan

While working at REDACTED-2, I reported the following issue.

The part of the REDACTED-A application that is implemented in AngularJS, has a few points for improvement, some easy, others less, and others practically unthinkable in the current state. The hope is that, by making the easy improvements now, the difficult ones over a period of time, the unthinkable will eventually become achievable.

Among the easy improvements we have the reorganization of the code in many independent files. This will then allow us to use modern JS code that we will later compile and optimize in ways that are now practically forbidden to us. (like tree-shaking)

Among the difficult improvements we have the refactoring to extract the web components from the application. Modern JS frameworks, including AngularJS from version 1.5 (we are currently using 1.4), allow you to structure an application in web components, which are then compiled to standard HTML, CSS, and JS.

Among the unthinkable improvements in the current state we have the migration of AngularJS to a framework that is going to last longer and is more modern. In September 2019 there are several top-tier options: Angular 8.2, React 16.9, and Vue 2.6.

How do we start?

The initial modernization plan that I propose contains many parts, all intended to change the application without causing disruption at the production level, and with minimal disruption at the development level.

  • Disconnect the Angular app from the Java app
  • Extract the Angular app into its separate repository
  • Transform the repository from Mercurial to Git
  • Format the code according to some standard
  • Compile the code to be able to use modern JS
  • Separate each functionality in its own file

How do we continue?

Previous changes viewed existing code as a black box, crafted in a certain way to produce an application, and we were only interested in crafting it in a different way to produce the same application.

So now we have an old AngularJS application inside a modern development environment. What we will do successively is to take advantage of this environment to renew the code as well.

  • Extract reusable code
  • Use Lodash
  • Use modern JS (ES6 +)
  • Use formal JSON validation
  • Extract components and services
  • Manage application settings
  • Manage application status
  • Automate end-to-end tests
  • Use GraphQL

And we will do all this little by little, while we continue to develop and maintain the application.

UPDATE 1

In 2019, I developed the new REDACTED-B and REDACTED-C applications:

  1. each one with VueJS and the Quasar component library
  2. each one in its own repository independent from that of the REDACTED-A application

After integrating it into REDACTED-A following the instructions in the tutorial

Migrating an Angular 1.x app to Vue 2.x
A ridiculously detailed and opinionated attempt to let Angular and Vue peacefully live together (if you wanna rock’n’roll)

the REDACTED-C application will remain as a guiding star for the successive and gradual migration of AngularJS.

UPDATE 2

The integration of REDACTED-C in a tab of the REDACTED-A application was a success, thanks to ocLazyLoad (a tool that we already had installed, but that we used in a sub-optimal way) that allowed us to reduce the boilerplate to unsuspected minimums.

Now, in light of this latest development, I think we can effectively migrate from AngularJS to VueJS after performing the Extract components and services step, for which the tutorial, whose steps I replicated and left “active” in REDACTED-C, marks a sufficiently simple and effective path.

Doing the migration sooner is unthinkable because the current code of the application is not only spaghetti, but also suffers from neglect problems at other levels, first of all the indiscriminate use of the $scope variable and the $timeout function. Because of this, it is very difficult to understand the execution context, and which parts of it are related to each sequential chunk of code.

We cannot introduce substantial changes such as those of migration without first putting order. In this phase we are only interested in partitioning the context into relevant blocks for each functionality (from spaghetti code to single concern). With this we will have a first intermediate version of the code, still in AngularJS, that we can easily compare with the old code. When everything works as before, we will migrate the first intermediate version in AngularJS to a second intermediate version in VueJS. It is very important that in this phase we reduce the changes to a minimum (for example, without also changing the names of things, however much it seems necessary), in order to be able to compare as easily as possible with the old code. When everything works as before, we can get down to work with refactoring and rewriting the code.

Important: we can carry out the migration in parts, starting with Extract components and services included, that is, considering first a controller, then another, then a whole application, taking advantage of the fact that AngularJS and VueJS can coexist without problems, as demonstrated by the tutorial.