L'équipe des outils de développement est une grande fan de TypeScript. À tel point que le nouveau code des outils de développement est écrit dans ce langage. Nous sommes en train de migrer l'ensemble du codebase pour qu'il soit vérifié par TypeScript. Pour en savoir plus sur cette migration, consultez notre présentation au Chrome Dev Summit 2020. Il était donc tout à fait logique d'envisager de migrer également le code de base de Puppeteer vers TypeScript.
Planifier la migration
Lorsque nous avons planifié la migration, nous voulions pouvoir progresser par petites étapes. Cela permet de réduire les frais généraux de la migration (vous ne travaillez que sur une petite partie du code à la fois) et de limiter les risques. En cas de problème avec l'une des étapes, vous pouvez facilement revenir en arrière. Puppeteer compte de nombreux utilisateurs. Une version défectueuse leur causerait des problèmes. Il était donc essentiel de minimiser le risque de modifications destructives.
Nous avons également eu la chance que Puppeteer dispose d'un ensemble robuste de tests unitaires couvrant toutes ses fonctionnalités. Cela nous a permis d'être sûrs de ne pas casser le code lors de la migration, mais aussi de ne pas introduire de modifications dans notre API. L'objectif de la migration était de la réaliser sans que les utilisateurs de Puppeteer ne se rendent compte que nous avions migré, et les tests étaient un élément essentiel de cette stratégie. Si nous n'avions pas eu une bonne couverture de test, nous l'aurions ajoutée avant de poursuivre la migration.
Toute modification de code sans test est risquée, mais les modifications qui touchent des fichiers entiers ou l'intégralité de la base de code sont particulièrement risquées. Lorsque vous apportez des modifications mécaniques, il est facile d'oublier une étape. À plusieurs reprises, les tests ont détecté un problème qui avait échappé à l'implémenteur et au réviseur.
Nous avons toutefois consacré du temps à la configuration de l'intégration continue (CI). Nous avons remarqué que les exécutions CI sur les demandes d'extraction étaient instables et échouaient souvent. Cela se produisait si souvent que nous avions pris l'habitude d'ignorer notre CI et de fusionner les demandes d'extraction de toute façon, en supposant que l'échec était un problème ponctuel sur CI plutôt qu'un problème dans Puppeteer.
Après quelques opérations de maintenance générales et un temps consacré à corriger certains tests instables réguliers, nous avons réussi à obtenir un état de réussite beaucoup plus cohérent, ce qui nous a permis d'écouter l'intégration continue et de savoir qu'un échec indiquait un véritable problème. Ce travail n'est pas glamour et il est frustrant de regarder des exécutions CI sans fin, mais il était essentiel que notre suite de tests fonctionne de manière fiable compte tenu du nombre de demandes d'extraction que la migration lui envoyait.
Sélectionner et déposer un fichier
À ce stade, notre migration était prête et nous disposions d'un serveur CI robuste rempli de tests pour nous protéger. Au lieu de nous lancer sur un fichier arbitraire, nous avons choisi un petit fichier à migrer. Cet exercice est utile, car il vous permet de valider le processus que vous prévoyez d'entreprendre. Si cela fonctionne sur ce fichier, votre approche est valide. Sinon, vous pouvez revenir à la case départ.
De plus, le fait de procéder fichier par fichier (et avec des versions régulières de Puppeteer, de sorte que toutes les modifications n'ont pas été déployées dans la même version npm) a permis de limiter les risques. Nous avons choisi DeviceDescriptors.js comme premier fichier, car il s'agissait de l'un des fichiers les plus simples du code. Il peut sembler un peu décevant de faire tout ce travail préparatoire pour une si petite modification, mais l'objectif n'est pas d'apporter des changements importants immédiatement, mais de procéder avec prudence et méthodiquement, fichier par fichier. Le temps passé à valider l'approche permet sans aucun doute de gagner du temps plus tard dans la migration, lorsque vous rencontrez des fichiers plus complexes.
Prouvez le schéma et répétez-le
Heureusement, la modification de DeviceDescriptors.js a bien été intégrée au codebase, et le plan a fonctionné comme prévu. À ce stade, vous êtes prêt à vous retrousser les manches et à vous y mettre, ce que nous avons fait. L'utilisation d'un libellé GitHub est un excellent moyen de regrouper toutes les demandes d'extraction, et nous avons trouvé cela utile pour suivre la progression.
Migrer et améliorer plus tard
Pour chaque fichier JavaScript, notre processus était le suivant :
- Renommez le fichier
.jsen.ts. - Exécutez le compilateur TypeScript.
- Corrigez les problèmes.
- Créez la demande d'extraction.
La majeure partie du travail dans ces demandes d'extraction initiales consistait à extraire des interfaces TypeScript pour les structures de données existantes. Dans le cas de la première demande d'extraction qui a migré DeviceDescriptors.js, comme nous l'avons vu précédemment, le code est passé de :
module.exports = [
{
name: 'Pixel 4',
… // Other fields omitted to save space
},
…
]
Et devient :
interface Device {
name: string,
…
}
const devices: Device[] = [{name: 'Pixel 4', …}, …]
module.exports = devices;
Dans le cadre de ce processus, nous avons examiné chaque ligne de la base de code pour détecter d'éventuels problèmes. Comme pour tout codebase qui existe depuis quelques années et qui s'est développé au fil du temps, il existe des opportunités de refactoriser le code et d'améliorer la situation. En particulier avec le passage à TypeScript, nous avons identifié des endroits où une légère restructuration du code nous permettrait de nous appuyer davantage sur le compilateur et d'obtenir une meilleure sûreté du typage.
De manière contre-intuitive, il est très important de ne pas effectuer ces modifications immédiatement. L'objectif de la migration est de transférer le codebase vers TypeScript. Tout au long d'une migration importante, vous devez penser au risque de provoquer des dysfonctionnements dans le logiciel et pour vos utilisateurs. En limitant au maximum les modifications initiales, nous avons réduit ce risque. Une fois le fichier fusionné et migré vers TypeScript, nous avons pu apporter des modifications supplémentaires pour améliorer le code afin d'exploiter le système de typographie. Assurez-vous de définir des limites strictes pour votre migration et essayez de les respecter.
Migrer les tests pour tester nos définitions de types
Une fois l'intégralité du code source migré vers TypeScript, nous avons pu nous concentrer sur nos tests. Nos tests avaient une excellente couverture, mais étaient tous écrits en JavaScript. Cela signifie qu'ils n'ont pas testé nos définitions de type. L'un des objectifs à long terme du projet (sur lequel nous travaillons encore) est de fournir des définitions de types de haute qualité prêtes à l'emploi avec Puppeteer, mais nous n'avions aucune vérification dans notre codebase concernant nos définitions de types.
En migrant les tests vers TypeScript (en suivant le même processus, fichier par fichier), nous avons découvert des problèmes avec notre TypeScript que les utilisateurs auraient sinon dû trouver pour nous. Désormais, nos tests couvrent non seulement toutes nos fonctionnalités, mais ils permettent également de vérifier la qualité de notre code TypeScript.
En tant qu'ingénieurs travaillant sur le codebase Puppeteer, nous avons déjà largement bénéficié de TypeScript. Associé à notre environnement d'intégration continue considérablement amélioré, il nous a permis de gagner en productivité lorsque nous travaillons sur Puppeteer et de faire en sorte que TypeScript détecte les bugs qui, autrement, auraient été intégrés à une version npm. Nous sommes ravis de proposer des définitions TypeScript de haute qualité pour permettre à tous les développeurs utilisant Puppeteer de bénéficier également de ce travail.
Télécharger les chaînes de prévisualisation
Envisagez d'utiliser Chrome Canary, Dev ou Beta comme navigateur de développement par défaut. Ces canaux de preview vous donnent accès aux dernières fonctionnalités des outils de développement, vous permettent de tester des API de plate-forme Web de pointe et vous aident à détecter les problèmes sur votre site avant vos utilisateurs.
Contacter l'équipe Outils pour les développeurs Chrome
Utilisez les options suivantes pour discuter des nouvelles fonctionnalités, des mises à jour ou de tout autre sujet lié aux outils pour les développeurs.
- Envoyez-nous vos commentaires et demandes de fonctionnalités sur crbug.com.
- Signalez un problème lié aux outils de développement en cliquant sur Autres options > Aide > Signaler un problème lié aux outils de développement dans les outils de développement.
- Tweetez sur @ChromeDevTools.
- Laissez des commentaires sur les vidéos YouTube "Nouveautés des outils pour les développeurs" ou les vidéos YouTube "Conseils sur les outils pour les développeurs".