Il y a 6 jours -

Temps de lecture 12 minutes

Comment nous avons migré notre frontend legacy vers NextJS

Article publié dans le cadre de la conférence FrontSide, dont leboncoin est partenaire.

Au fil des années, les besoins et les attentes des internautes ont évolué. Aujourd’hui, nous attendons un site web très réactif, beau et attrayant. « Ça marche » est loin d’être suffisant.

Techniquement, leboncoin.fr ne ressemble en rien à l’ancienne version que nous avons lancée il y a 15 ans. Nous avons conservé l’esprit original de la plateforme, notre identité et nos incroyables utilisateurs, mais en interne, leboncoin a beaucoup changé ces dernières années.

L’évolution rapide des nouveaux frameworks Front-end nous fait repenser la manière dont nous abordons ces nouveaux défis technologiques.

Aujourd’hui, nous sommes plus de 40 développeurs web répartis dans 20 équipes (features teams). Nous avons environ 200 000 lignes de codes et une quantité incalculable de fonctionnalités.

Et nous continuons à nous développer !

Aujourd’hui, je vais vous expliquer comment nous avons réalisé la migration d’une aussi grande base de code sur NextJS, le framework React.

Pourquoi avons-nous besoin de ce changement ?

Après une longue et douloureuse migration d’un framework maison vers React il y a 3 ans, nous avons rapidement été confrontés au même problème une nouvelle fois.

Lors de la réécriture sur React, nous avons choisi RocJS, un framework qui nous a permis de s’affranchir d’une bonne partie de la configuration et de se consacrer directement au développement.

La Core team et les principaux contributeurs de Roc travaillaient chez Schibsted, le groupe qui possède leboncoin. Cela semblait être une super occasion pour nous de collaborer, de partager et d’apprendre ensemble !

Bien que la promesse était sur le papier attrayante et que le framework assez populaire à l’époque, il s’est révélé être rapidement obsolète…

Nous avons passé beaucoup de temps à migrer vers React, et 2 ans et demi plus tard, nous ne pouvions plus nous séparer de Webpack 1, React 15 et react-router v3.

A ce moment-là, nous nous sommes sentis coincés et dans le besoin désespéré de sortir de cette situation.

React 16 était sur le point de sortir et nous étions tous impatients de l’intégrer.

La bonne nouvelle était que la migration de React 15 à React 16 serait (en principe) bien plus facile que la précédente réécriture.

Mais… mois après mois, de nouvelles fonctionnalités ont été ajoutées à la codebase, et nous avions maintenant BEAUCOUP de fichiers/composants/pages.

En outre, nous avions du mal à diviser le code et à l’optimiser (avoir un framework “boîte noire” au-dessus de Webpack v1 n’est peut-être pas une si bonne idée après tout).

De plus, le référencement et les performances sont très importants pour nous, nous ne pouvions donc pas nous permettre de laisser notre site web être aussi lent.

À ce stade, nous avons commencé à réfléchir à nos choix, et nous avons envisagé 3 possibilités : 

  • Prendre l’ownership de RocJS, et commencer vraiment à y contribuer.
  • Construire notre propre serveur Node (basé sur Express) et tout l’écosystème pour construire, assembler et faire fonctionner notre application web.
  • Migrer vers un nouveau framework.

Nous avons d’abord décidé de miser sur RocJS, et nous avons commencé à étudier le cadre et à voir les possibilités d’amélioration.

Malheureusement, nous avons rapidement réalisé que toute la codebase était très difficile à comprendre et qu’il faudrait des mois pour la maîtriser. Nous ne pouvions pas constituer une équipe entière pour y travailler à long terme et, surtout, nous ne voulions pas être à nouveau bloqués à l’avenir. Maintenir un cadre de travail prend du temps et nécessite beaucoup de ressources.

Et voici NextJS !

Heureusement, chez leboncoin, nous avons droit à une journée entière toutes les deux semaines pour expérimenter, remanier et travailler sur des POC. Nous l’appelons la « journée guilde » et elle permet à chaque développeur de s’exprimer et de partager ses expériences et ses problèmes.

C’est à cette époque que nous avons essayé et expérimenté NextJS.

Next.js est un framework React avec une grande communauté et une équipe très réactive 🎺 concernant les mises à jour majeures de React et de ses outils. De plus, certains de nos développeurs en avaient déjà entendu parler.

Facile à apprendre, bien documenté, personnalisable, avec une communauté très cool et disponible sur Spectrum, nous avons tout de suite adoré NextJS !

Au début, nous avons choisi quelques pages faciles et nous les avons fait tourner uniquement en développement. Nous étions assez satisfaits du résultat, le passage de “l’ancien code » au nouveau était assez simple et nous avons apprécié la façon dont NextJS nous a permis de modifier tout ce dont nous avions besoin tout en fournissant une configuration très optimisée dès le départ.

Ensuite, nous avons passé du temps à expliquer le fonctionnement de NextJS et nous nous sommes assurés que tous les développeurs web validaient la solution (heureusement pour nous, Next a une très bonne documentation).

Au bout d’un moment, nous étions prêts ! Le plan était simple, nous allions “forker” notre dépôt vers un nouveau et nous allions nous débarrasser de RocJS pour le remplacer par NextJS.

L’équipe Core était chargée de la migration et a pu y consacrer tout son temps.

En quelques semaines seulement, nous avions des pages existantes qui fonctionnaient « en quelque sorte » avec NextJS.

Pourquoi en quelque sorte ? Eh bien, même si les pages étaient affichées, nous avions une avalanche d’avertissements et d’erreurs qui apparaissaient partout dans la console. Et parce que les pages étaient écrites avec l’ancienne logique, beaucoup d’améliorations de NextJS ne fonctionnaient pas.

Mais c’était un beau premier pas. Le vrai problème était la stratégie que nous avions adoptée pour faire migrer les pages. Nous avons décidé que chaque jour, nous rebaserions le nouveau code publié par chaque développeur sur l’ancien dépôt git sur le nouveau afin d’être toujours à jour.

Et je pense que les deux développeurs de l’équipe Core qui ont géré cette migration en font encore des cauchemars aujourd’hui.

En effet, comme nous avons plus de 40 développeurs web, ils passaient des heures à rapatrier le nouveau code chaque jour ! Pire encore, lorsque les développeurs de l’équipe Core apportaient des modifications au nouveau dépôt, ils devaient s’assurer que rien n’était perdu lors de la refonte, ce qui signifie qu’ils devaient souvent s’asseoir à côté de chaque développeur ayant réalisé une fonctionnalité ce jour-là, afin de s’assurer que tout était ok.

Puis nous avons pris du recul

De toute évidence, cette approche n’était pas viable et nous ne pouvions pas demander à chaque développeur de créer une nouvelle fonctionnalité directement sur le dépôt Next et d’oublier l’ancien. Aucun manager sur terre n’aurait accepté de parier le temps de ses développeurs sur une nouvelle technologie lancée à l’occasion des journées guilde.

Nous avons décidé de réunir un petit groupe de développeurs volontaires pour réfléchir à la manière dont nous devrions aborder cette question de manière intelligente.

Premièrement, nous devions mettre fin à cette absurdité de rebase. Nous supprimerions toutes les « anciennes » pages du dépôt Next et n’autoriserions que les nouvelles.

Deuxièmement, nous créerions un moyen pour les développeurs de migrer leurs pages avec le moins de contrainte possible.

Et c’est ainsi que notre Design System est né !

Jusqu’à présent, chaque composant était créé à l’intérieur du dépôt git, et chaque développeur choisissait ce dont il avait besoin. Le problème était que personne dans l’équipe UX ne savait à quoi ces composants ressemblaient, et chaque feature team avait commencé à faire ses propres implémentations.

Le Design System de Leboncoin

L’idée était d’isoler le plus possible les éléments de présentation et de faire en sorte que les pages ne demandent que ce dont elles ont besoin. De cette façon, les pages elles-mêmes seraient beaucoup plus petites et donc plus faciles à migrer, exemptes de tout composant et ne contenant que la logique métier.

Une fois de plus, nous avons utilisé les « journée guilde » et le temps de la Core team pour créer ces éléments.

Nous avons décidé de créer un nouveau dépôt git. Un monorepo-multi paquets géré par lerna. De cette façon, chaque composant serait au même endroit et disponible pour chaque projet leboncoin.

Nous avons également créé un Storybook, mis à jour à chaque merge afin que l’équipe UX puisse vérifier notre travail et y contribuer en temps réel.

Nous avons passé des mois à créer de nouveaux composants, jusqu’à ce que nous estimions avoir une bibliothèque suffisamment fournie.

Celle-ci était en fait plus facile à vendre, en embarquant l’équipe UX avec nous, tout le monde a vu un avantage à cette approche et nous étions libres d’y consacrer plus de temps.

Une fois que notre design system était bien fourni avec pleins de beaux éléments, nous sommes revenus à notre objectif initial et avons commencé à travailler sur la migration des pages.

Vers l’infini et au-delà

Nous étions convaincus que la migration serait désormais beaucoup plus facile. Mais comme elle était encore difficile à “vendre” en interne, les lead développeurs et l’équipe Core – étaient les seuls à passer du temps et à travailler dessus.

De cette façon, ils étaient d’abord les premiers confrontés aux bugs, parfois chronophages et aux défaillances du process. 

Nous avons commencé avec des pages isolées qui ne nuisaient pas trop à l’activité de l’entreprise.

Et en effet, il a fallu du temps entre la première itération sur la nouvelle page et le moment où elle est entrée en production !

Nous devions créer un nouveau flux pour déployer des images sur Docker avec Kubernetes (nous utilisions jusqu’alors des package Debian pour l’application Web). Mais grâce à notre incroyable équipe Infra, cela n’a pas été si pénible pour nous.

Vous pouvez trouver plus d’informations sur notre pipeline de déploiement ici : https://medium.com/leboncoin-engineering-blog/leboncoin-commits-life-960a86cd35ff

Nous avons commencé à migrer de plus en plus de petites pages isolées pour prouver que tout était sous contrôle et que nous pouvions continuer à avancer la migration.

Ensuite, nous étions enfin en capacité de gérer la migration à une plus grande échelle ! Chaque développeur passait toute sa journée de guilde (le lundi) à travailler sur la migration des pages, et il faisait les rebase sur le dépôt next (il est bien plus facile de rebase son propre code ;)).

Pour rendre le nouveau dépôt encore plus attrayant, nous avons cessé de mettre à jour les dépendances de l’ancien et nous nous sommes abstenus de l’améliorer. De cette façon, si les développeurs web voulaient essayer toutes les nouvelles fonctionnalités et améliorations, ils devaient faire l’effort de migrer leurs pages.

Le point de bascule a été lorsque l’équipe chargée de la recherche (Search Team) a accepté de migrer une énorme page (la page d’accueil !) vers NextJS.

Quatre développeurs Web ont passé deux mois à créer de nouveaux composants d’interface utilisateur (UI) et ont joué avec les nouvelles fonctionnalités de React.

“La meilleure partie d’une migration est de prendre le temps de repenser la logique du code. Un code écrit il y a trois ans n’est peut-être plus pertinent aujourd’hui.”

Et maintenant que nous avons beaucoup d’éléments de présentation, nous pouvons passer plus de temps à « nettoyer » les pages.

La nouvelle page d’accueil de leboncoin sur NextJS

La migration de la page d’accueil a été douloureuse, mais elle a néanmoins été un succès et a ouvert la voie au reste de l’application Web.

Maintenant, les grandes pages comme les petites annonces, la messagerie, le profil, les transactions, … sont toutes déployées par NextJS !

Et ce n’est pas fini !

Nous avons réussi à convaincre tout le monde que la migration vers NextJS était nécessaire et qu’elle fonctionne !

Qu’avons-nous appris ?

Au cours de ce projet de 3 ans, nous avons beaucoup appris !

Tout d’abord, nous avons appris que le fait de laisser aux développeurs le temps d’expérimenter porte ses fruits.

Même si ce ne sont pas ceux qui regardent les mesures utilisateurs toute la journée, ils veulent toujours ce qu’il y a de mieux pour les utilisateurs finaux et ils peuvent y contribuer grandement.

De plus, la première idée peut et va probablement échouer. Ce n’est pas un problème. Nous avons appris de nos erreurs et nous avons amélioré notre approche. L’important est de comprendre ce qui a mal tourné et ce que nous pouvons mieux faire.

Continuez à y croire ! En trois ans, nous sommes passés d’un « petit projet au fond du garage » à une « grande migration intégrée dans la feuille de route de chaque équipe ». Vous ne pouvez pas y arriver si vous ne croyez pas en ce que vous faites, car personne d’autre n’y croira pour vous.

Nous pouvons continuer à nous améliorer ! La migration sur NextJS n’est qu’une première étape. Nous pouvons maintenant nous concentrer sur les performances et l’optimisation et nous assurer de fournir la meilleure expérience possible.

Version originale de l’article en anglais à retrouver sur Medium

→ Plus d’infos (blog tech, vidéos, events etc.) sur leboncoin.tech

Cet article à été rédigé par Thibaut Sabot,  Lead developer Web @leboncoin, partenaire de notre conférence FrontSide.

Commentaire

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Nous recrutons

Être un Sapient, c'est faire partie d'un groupe de passionnés ; C'est l'opportunité de travailler et de partager avec des pairs parmi les plus talentueux.