Longevity Response: How We Updated the Lingualeo Front End
“If you are not ashamed of the first version of your product, then you are late for entering the market”
These words justify the development of the Lingualeo frontend from the very beginning, since 2010. In a complex multi-platform product with a 5-year history, the code is layered a little thicker than soil layers over the archaeological Tripoli culture. And now, this day has come: we decided to scatter and jump as it should, updating the web-client platform. Below we will tell you what we did to land as far as possible from the reference point.
The PR woman, who was recklessly trying to dig into the understanding of all this, had to say that the main technologies on which the Lingualeo frontend is based are crutches and bicycles. We hope she is smart enough not to write this on Habr.
Step one. Dig up PR manager
The Lingualeo frontend runs on a bunch of different libraries, with code distributed from places where sadness is pichal to places where the bleeding edge is also a kind of sadness-pichal :-D. In ancient times, on the Lingualeo website, it all started with js files interspersed with jQuery. Then it became necessary to break it, and some kind of “widgets” appeared, to which the global event bus was screwed. The widget system itself underwent several iterations until we decided to move on to the so-called component approach. After some hesitation and searching, we added a bit of entropy to the hustle and bustle around React .
Step Two Blind, from what was, and add a little from myself
So, for those who are far from the topic and too lazy to go to the link above, we inform: React is a JS library for building user interfaces. By the time our experiments began, React was released in version 0.13. With him and got to work. It was not possible to make friends with React directly for several reasons:
- we needed to somehow support and cross the previous code and the code on React,
- at the start, I didn’t want to abandon the usual text templates,
- it was interesting to dig deeper and write something of your own,
- our collector (who is also many years old) did not learn how to work with jsx.
So we decided to write our own “wrapper”, and use the ready-made system for creating and working with Virtual DOM:
- https://github.com/Matt-Esch/virtual-dom to build a Virtual DOM and compare it with the previous Virtual DOM,
- https://github.com/marcelklehr/vdom-virtualize - to convert html to Virtual DOM,
- https://github.com/nthtran/vdom-to-html - to convert Virtual DOM to html (we thought it would be useful, but no, we use it mainly for debugging).
By the way, we already mentioned this in a post about a new grammar training .
They tried to write a wrapper with API compatibility with React components, that is, going through the same life cycle with the following hooks:
(componentWillMount, componentDidMount, componentWillUnmount,
So you can look for some general cases as if we are working with React, and there’s a groundwork for an easier transition to React without rewriting all components.
Step Three Go down to earth and love life again
All the euphoria from switching to a conceived plan with Virtual DOM got a little dull when the question of how to deal with the flow of data and the processing of user events matured. The Flux architectural approach seemed like a very abstract solution to us. Having written with his help the first version of the new grammar training , we moved back and turned towards Redux . We consider this approach more direct and concise: a single data warehouse, the presence of middlewares, and our favorite clean handler functions as event handlers. But we would not be us without writing our own layer for the implementation of this approach, for which there were several different reasons. The latter, basically, rested on our collector: it does not support ES6, on which Redux is written.
Step Four Dream and embody
As a result, we are slowly reaching for a brighter future in which:
- in the components of the minimum business logic, they simply reflect the state and listen to events from the user;
- all business logic (reaction to events) accumulates inside the store, or rather, Reducer, returning the new state of the store based on the old state and action;
- some asynchronous actions are taken out in action creators or even in middlewares;
- animation - our stumbling block, the horror of all front-end-machines - is stuffed into components (not everyone has confidence in the correctness of this approach).
In fact, there is still grinding in on this approach, and not all questions are obvious answers, as in the case of animation, for example, but in general we like this approach and make life easier in the places where it is implemented.
The plans for the future include the transition to Virtual DOM throughout the site and the introduction of the
By the way, we will be very grateful to the Habrovsk people for comments on how they work with animation in React: they are interested in difficult cases when several interacting animations occur, or when interacting with a component during animation). And the question of how the transition from one architecture to another was carried out is interesting for us too ;-)
Yours truly, the Lingualeo frontend team.
Follow our news on Twitter , Facebook , vkontakte and Instagram .
Off topic: Lingualeo is waiting in its ranks iOS and Android developers. Read all open vacancies on the blog at lingualeo.com. Waiting for your resume!