Comment migrer une application Angular.Js vers Angular ?

Affluences propose deux applications web :

un portail d’administration à destination des établissements partenaires

et un site de réservation proposé aux visiteurs afin qu’ils puissent réserver en deux clics une salle de travail ou un atelier.

Ces deux applications ont commencés à être développées à partir de 2015. Nous avions fait le choix d’utiliser Node.Js pour le backend et l’API. Côté frontend, nous avions décidé d’utiliser Angular.Js. Ces deux outils nous semblaient être les plus adaptés à nos besoins mais également en adéquation avec nos affinités technologique.

Mais nos besoins ont évolué au fur et à mesure que nos utilisateurs se faisaient de plus en plus nombreux. Nous avions besoin d’outils plus robustes nous permettant de proposer toujours plus de nouvelles fonctionnalités tout en garantissant la stabilité et la montée en charge de nos applications.

Côté backend et API, nous avons traduit notre base de code Javascript en Typescript pour profiter des améliorations apportées par ce langage (compilation, typage fort, …). Ce changement étant invisible d’un point de vue utilisateur, nous avons pu l’opérer petit à petit en parallèle de la mise en production de nouvelles fonctionnalités. Côté frontend, nous avions décidé de passer sur Angular, l’évolution majeure d’AngularJs. Contrairement aux apparences, la migration vers Angular depuis Angular.Js n’est pas naturelle et implique plusieurs changements structurels comme le passage à des composants web qui a nécessité l’implémentation d’outils supplémentaires comme NgRx par exemple. C’est pourquoi nous avons élaboré un plan de migration pour chacune de nos applications.

Nous avons d’abord commencé par le site de réservation. Celui-ci représentant peu de pages par rapport au portail d’administration, nous avons décidé de réécrire complètement la base de code. Hormis le fonctionnement général de l’application, l’un des points sur lequel nous avons porté notre attention concernait la compatibilité des URL entre les deux versions. Angular proposant son propre routeur, nous avons dû assurer la redirection des anciens formats d’URL vers le nouveau. Cette problématique représentait un réel besoin puisque le service se base sur la vérification de l’adresse mail de l’utilisateur à travers un lien qui lui est envoyé lorsqu’il effectue sa réservation.

Le passage vers Angular a également été l’occasion de réactualiser le design général.

Forts de ce retour d’expérience, nous avons élaboré un plan différent pour le portail d’administration. Celui-ci représentant une complexité plus importante de par son nombre de pages et par le nombre d’interactions possibles, nous avons décidé de faire cohabiter Angular.Js et Angular en traduisant petit à petit les différents modules de l’ancien framework vers le nouveau. Nous avons dans un premier temps re-développé les modules communs (header, footer, éléments de navigation, …) afin que la passage d’une version à l’autre soit le plus transparent possible pour l’utilisateur. En s’appuyant sur ces composants, nous traduisons maintenant chaque module dès qu’une nouvelle fonctionnalité doit y être ajoutée.

Chacune de ces méthodes propose donc certains avantages: la traduction complète assure une migration définitive mais peut s’avérer complexe dans le cadre de projets avec beaucoup de pages. La cohabitation des deux frameworks peut quant à elle être utile pour assurer une migration progressive de gros projets mais ne doit pas perdurer dans le temps sous peine de devoir maintenir deux fois plus de code.

Comment assurer la transition entre une application native et une application hybride Flutter ?

Process de migration des données locales, phase de tests, différences entre les builds release et debug, …

Aperçu de l'application mobile Affluences nouvelle génération
Aperçu de la nouvelle application mobile Affluences : téléchargez-la !

Nous vous parlions il y a quelques temps de la toute nouvelle version de l’application faite avec Flutter, qui était en développement et bientôt disponible au publique.

C’est chose faite ! Nous avons pour l’instant lancé une publication progressive sur le Play Store et l’App Store (bientôt complète) !
Le but de cet article est d’expliquer comment nous avons fait la transition de notre version native (Android et iOS) à la version cross-platform Flutter.

Nous voulions par exemple garder certaines préférences de l’utilisateur afin d’assurer une transition “fluide”. Nous utilisons le plugin “SharedPreferences” sur Flutter pour stocker ces préférences. Malheureusement, ce plugin n’utilise pas le même fichier que notre version native. Nous avons donc dû écrire du code natif (Kotlin et Swift), spécifique à notre besoin pour pouvoir récupérer les anciennes préférences et les stocker dans les nouvelles.

Le fait de devoir migrer ces données nous a notamment permis de découvrir un bug dû à ProGuard sur les versions natives qui, heureusement, n’a pas été bloquant sur la migration. En effet, le modèle concernant certaines préférences était obfusquées. Les clés du JSON sauvegardé n’étaient donc plus identiques (ex: “app_startup” devenait “a”). Nous avons contourné ce problème en utilisant les valeurs offusquées pour migrer les données.

Au tout début du développement, Flutter était à la version 1.2.1, au fur et à mesure nous mettions Flutter à jour, pour aujourd’hui être à la version 1.6.3. Cela a notamment permis de corriger certains bugs, comme par exemple les minutes des TimePicker qui n’était pas sélectionnées automatiquement.

Il n’y a rien de pire que de publier une mise à jour qui rend inutilisable une application. C’est pourquoi, différentes phases de tests ont eu lieu avant la publication afin de nous assurer que la migration des données fonctionne correctement et qu’aucun bug n’est présent. Il y a eu dans un premier temps des BETA toutes les deux semaines, restreintes à quelques personnes, puis des Release Candidate toutes les semaines, avec un nombre d’utilisateurs un peu plus important. Cela nous a permis d’identifier des bugs restants et certains points à améliorer, que ce soit niveau UI ou UX. En complément, nous avons mis en place différents tests unitaires ainsi que des tests d’intégration afin d’assurer la pérennité de l’application et éviter d’éventuelles régressions dans les futures mise à jour.

Malgré le changement majeur de technologie et l’ajout de nombreuses nouvelles fonctionnalités, tous ces mécanismes nous ont permis de lancer cette nouvelle version tant attendue avec sérénité. Cette base solide va nous permettre de consolider notre cycle de développement et de proposer de nouvelles fonctionnalités toujours plus rapidement !