L'équipe DevTools est une grande fan de TypeScript. À tel point que nous écrivons du nouveau code dans DevTools et que nous sommes en pleine migration de l'intégralité du codebase pour qu'il soit vérifié par TypeScript. Pour en savoir plus sur cette migration, consultez notre présentation lors du Chrome Dev Summit 2020. Il était donc tout à fait logique d'envisager de migrer le code de base de Puppeteer vers TypeScript.
Planifier la migration
Lorsque nous avons planifié la migration, nous voulions avancer par petites étapes. Cela réduit les coûts de la migration (vous ne travaillez que sur une petite partie du code à la fois) et les risques. En cas de problème avec l'une des étapes, vous pouvez facilement la rétablir. Puppeteer compte de nombreux utilisateurs, et une version défectueuse causerait des problèmes à beaucoup d'entre eux. Il était donc essentiel de limiter au maximum le risque de modifications défectueuses.
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 de nous assurer que nous ne cassons pas le code lors de la migration, mais aussi que nous n'apportons pas de modifications à notre API. L'objectif de la migration était de la mener à bien sans que les utilisateurs de Puppeteer ne s'en rendent même compte. Les tests ont joué un rôle essentiel dans cette stratégie. Si nous n'avions pas eu une bonne couverture de test, nous l'aurions ajouté avant de poursuivre la migration.
Effectuer une modification de code sans tests est risqué, mais les modifications qui touchent des fichiers entiers ou l'intégralité du codebase sont particulièrement risquées. Lorsque vous apportez des modifications mécaniques, il est facile de manquer une étape. À plusieurs reprises, les tests ont détecté un problème qui avait échappé à l'implémentateur et à l'examinateur.
Nous avons consacré du temps à la configuration de l'intégration continue (CI). Nous avons constaté que les builds CI sur les demandes de tirage étaient instables et échouaient souvent. Cela se produisait si souvent que nous avions pris l'habitude d'ignorer notre CI et de fusionner les requêtes pull, en supposant que l'échec était un problème ponctuel sur la CI plutôt qu'un problème dans Puppeteer.
Après une maintenance générale et un temps consacré à corriger des erreurs de test régulières, nous avons obtenu un état de réussite beaucoup plus cohérent, ce qui nous a permis d'écouter la CI et de savoir qu'un échec indiquait un problème réel. Ce travail n'est pas glamour, et il est frustrant de voir des exécutions de CI sans fin, mais il était essentiel que notre suite de tests fonctionne de manière fiable compte tenu du nombre de requêtes pull que la migration lui envoyait.
Sélectionner et placer un fichier
À ce stade, notre migration était prête et nous disposions d'un serveur CI robuste rempli de tests pour nous protéger. Plutôt que de nous lancer dans la migration d'un fichier arbitraire, nous avons choisi un petit fichier à migrer. Cet exercice est utile, car il vous permet de valider le processus planifié que vous êtes sur le point d'entreprendre. Si cela fonctionne avec ce fichier, votre approche est valide. Dans le cas contraire, vous pouvez revenir à la planche à dessin.
En outre, en procédant par fichier (et avec des versions régulières de Puppeteer, de sorte que toutes les modifications ne soient pas publiées dans la même version npm), nous avons réduit le risque. Nous avons choisi DeviceDescriptors.js
comme premier fichier, car il s'agit de l'un des fichiers les plus simples du codebase. Il peut sembler un peu décevant de réaliser tout ce travail de préparation pour obtenir une si petite modification, mais l'objectif n'est pas d'apporter d'énormes changements immédiatement, mais de procéder avec prudence et méthodiquement, fichier par fichier. Le temps passé à valider l'approche vous permet de gagner du temps plus tard dans la migration lorsque vous rencontrez des fichiers plus complexes.
Valider le modèle et le répéter
Heureusement, le changement vers DeviceDescriptors.js
a bien été intégré au codebase, et le plan a fonctionné comme nous l'espérions. À ce stade, vous êtes prêt à vous mettre au travail, ce qui est exactement ce que nous avons fait. L'utilisation d'un libellé GitHub est un excellent moyen de regrouper toutes les demandes d'extraction. Nous avons trouvé cela utile pour suivre la progression.
Migrer et améliorer plus tard
Pour chaque fichier JavaScript, nous avons suivi la procédure suivante:
- Renommer le fichier
.js
en.ts
. - Exécutez le compilateur TypeScript.
- Résoudre les problèmes.
- Créez la demande d'extraction.
La majeure partie du travail dans ces requêtes pull initiales consistait à extraire des interfaces TypeScript pour les structures de données existantes. Dans le cas de la première requête pull qui a migré DeviceDescriptors.js
, le code est passé de:
module.exports = [
{
name: 'Pixel 4',
… // Other fields omitted to save space
},
…
]
Et est devenu:
interface Device {
name: string,
…
}
const devices: Device[] = [{name: 'Pixel 4', …}, …]
module.exports = devices;
Dans le cadre de ce processus, nous avons examiné chaque ligne du codebase à la recherche de problèmes. Comme pour tout codebase qui existe depuis quelques années et qui a évolué au fil du temps, il existe des possibilités de refactorisation du code et d'amélioration de 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'améliorer la sécurité des types.
Contrairement à ce que l'on pourrait penser, il est très important de ne pas effectuer ces changements immédiatement. L'objectif de la migration est de convertir la base de code en TypeScript. Tout au long d'une migration importante, vous devez toujours penser au risque de causer des pannes au logiciel et à vos utilisateurs. En limitant les modifications initiales, nous avons réduit ce risque. Une fois le fichier fusionné et migré vers TypeScript, nous avons pu apporter des modifications ultérieures pour améliorer le code et exploiter le système de types. Veillez à définir des limites strictes pour votre migration et à essayer de les respecter.
Migrer les tests pour tester nos définitions de types
Une fois que nous avons migré l'intégralité du code source vers TypeScript, nous avons pu nous concentrer sur nos tests. Nos tests avaient une couverture optimale, mais ils étaient tous écrits en JavaScript. Par conséquent, nos définitions de type n'ont pas été testées. L'un des objectifs à long terme du projet (sur lequel nous travaillons toujours) est de fournir des définitions de type de haute qualité prêtes à l'emploi avec Puppeteer. Toutefois, nous n'avions aucune vérification dans notre codebase concernant nos définitions de type.
En migrant les tests vers TypeScript (en suivant le même processus, fichier par fichier), nous avons détecté des problèmes avec notre TypeScript qui auraient autrement été laissés à la charge des utilisateurs. Désormais, nos tests couvrent non seulement toutes nos fonctionnalités, mais servent également de contrôle qualité de notre TypeScript.
En tant qu'ingénieurs travaillant sur le codebase Puppeteer, nous avons déjà beaucoup bénéficié de TypeScript. Associé à notre environnement de CI beaucoup amélioré, cela nous a permis d'être plus productifs lorsque nous travaillons sur Puppeteer et de laisser TypeScript détecter les bugs qui auraient autrement été inclus dans une version npm. Nous sommes ravis de pouvoir proposer des définitions TypeScript de haute qualité pour que tous les développeurs utilisant Puppeteer puissent également en profiter.
Télécharger les canaux de prévisualisation
Envisagez d'utiliser Chrome Canary, Dev ou Bêta comme navigateur de développement par défaut. Ces canaux de prévisualisation vous donnent accès aux dernières fonctionnalités de DevTools, vous permettent de tester les API de plate-forme Web de pointe et vous aident à détecter les problèmes sur votre site avant vos utilisateurs.
Contacter l'équipe des outils pour les développeurs Chrome
Utilisez les options suivantes pour discuter des nouvelles fonctionnalités, des mises à jour ou de tout autre élément lié aux outils pour les développeurs.
- Envoyez-nous vos commentaires et vos demandes de fonctionnalités sur crbug.com.
- Signalez un problème dans les outils de développement à l'aide de l'icône Plus d'options > Aide > Signaler un problème dans les outils de développement dans les outils de développement.
- Envoyez un tweet à @ChromeDevTools.
- Laissez des commentaires sur les vidéos YouTube sur les nouveautés des outils pour les développeurs ou sur les vidéos YouTube sur les conseils concernant les outils pour les développeurs.