Migreren van poppenspeler naar TypeScript

We zijn grote fans van TypeScript in het DevTools-team, zo erg zelfs dat er nieuwe code in DevTools in wordt geschreven en we zitten midden in een grote migratie van de hele codebase naar typecontrole door TypeScript. U kunt meer over die migratie te weten komen in onze lezing op Chrome Dev Summit 2020 . Het was daarom volkomen logisch om ook te kijken naar het migreren van de codebase van Puppeteer naar TypeScript.

Het plannen van de migratie

Bij het plannen van de migratie wilden we in kleine stapjes vooruitgang kunnen boeken . Hierdoor blijft de overhead van de migratie beperkt (u werkt op elk moment slechts aan een klein deel van de code) en beperkt u ook het risico. Als er iets misgaat met een van de stappen, kunt u dit eenvoudig ongedaan maken. Puppeteer heeft veel gebruikers en een kapotte release zou voor veel van hen problemen veroorzaken, dus het was van cruciaal belang dat we het risico op het niet goed functioneren van wijzigingen tot een minimum beperkten.

We hadden ook het geluk dat Puppeteer over een robuuste reeks unit-tests beschikt die alle functionaliteit bestrijken. Dit betekende dat we er zeker van konden zijn dat we tijdens de migratie geen code kapotmaakten, maar ook dat we geen wijzigingen in onze API doorvoerden. Het doel van de migratie was om deze te voltooien zonder dat Puppeteer-gebruikers zich zelfs maar realiseerden dat we waren gemigreerd, en de tests waren een essentieel onderdeel van die strategie. Als we geen goede testdekking hadden gehad, hadden we die toegevoegd voordat we verder gingen met de migratie.

Het uitvoeren van codewijzigingen zonder tests is riskant, maar wijzigingen waarbij u hele bestanden of de gehele codebase aanraakt, zijn bijzonder riskant. Bij het aanbrengen van mechanische wijzigingen is het gemakkelijk om een ​​stap te missen, en bij meerdere gelegenheden stuitten de tests op een probleem dat zowel de uitvoerder als de recensent was ontgaan.

Eén ding waar we vooraf tijd in hebben geïnvesteerd, was onze Continuous Integration (CI)-opstelling . We hebben gemerkt dat CI-runs tegen pull-aanvragen zwak waren en vaak mislukten. Dit gebeurde zo vaak dat we de gewoonte hadden gekregen om onze CI te negeren en de pull-aanvragen toch samen te voegen, ervan uitgaande dat de fout een eenmalig probleem was op CI en niet een probleem in Puppeteer.

Na wat algemeen onderhoud en toegewijde tijd om enkele reguliere testvlokken te repareren, hebben we het in een veel consistentere staat van doorgang gebracht, waardoor we naar CI konden luisteren en weten dat een storing op een daadwerkelijk probleem duidde. Dit werk is niet glamoureus, en het is frustrerend om naar eindeloze CI-runs te kijken, maar het was van cruciaal belang om ons testpakket betrouwbaar te laten werken gezien het aantal pull-aanvragen dat de migratie met zich meebracht.

Kies en plaats één bestand

Op dit punt hadden we onze migratie klaar voor gebruik en een robuuste CI-server vol tests om ons te beschermen. In plaats van in een willekeurig bestand te duiken, hebben we doelbewust een klein bestand uitgekozen om te migreren . Dit is een nuttige oefening omdat u hiermee het geplande proces dat u gaat ondernemen, kunt valideren. Als het op dit bestand werkt, is uw aanpak geldig; zo niet, dan kun je teruggaan naar de tekentafel.

Bovendien werd het risico laag gehouden door bestand voor bestand te gaan (en met reguliere Puppeteer-releases, zodat alle wijzigingen niet in dezelfde npm-versie werden verzonden). We kozen DeviceDescriptors.js als het eerste bestand , omdat het een van de meest eenvoudige bestanden in de codebase was. Het kan een beetje teleurstellend zijn om al dit voorbereidende werk te doen en zo'n kleine verandering binnen te halen, maar het doel is niet om onmiddellijk grote veranderingen door te voeren, maar om voorzichtig en methodisch bestand voor bestand te werk te gaan. De tijd die u besteedt aan het valideren van de aanpak bespaart zeker tijd later in de migratie als u op de meer gecompliceerde bestanden stuit.

Bewijs het patroon en herhaal

Gelukkig is de wijziging in DeviceDescriptors.js met succes in de codebase terechtgekomen en werkte het plan zoals we hadden gehoopt! Op dit punt ben je klaar om de knoop door te hakken en door te gaan, en dat is precies wat we deden . Het gebruik van een GitHub-label is een hele leuke manier om alle pull-aanvragen te groeperen, en we vonden dat handig om de voortgang bij te houden.

Laat het migreren en verbeter het later

Voor elk afzonderlijk JavaScript-bestand was ons proces:

  1. Hernoem het bestand van .js naar .ts .
  2. Voer de TypeScript-compiler uit.
  3. Los eventuele problemen op.
  4. Maak de pull-aanvraag .

Het meeste werk bij deze initiële pull-aanvragen bestond uit het extraheren van TypeScript-interfaces voor bestaande datastructuren. In het geval van het eerste pull-verzoek waarmee DeviceDescriptors.js werd gemigreerd, dat we eerder hebben besproken, ging de code van:

module.exports = [
  { 
    name: 'Pixel 4',
    … // Other fields omitted to save space
  }, 
  …
]

En werd:

interface Device {
  name: string,
  …
}

const devices: Device[] = [{name: 'Pixel 4', …}, …]

module.exports = devices;

Als onderdeel van dit proces betekende dit dat we elke regel van de codebase doorliepen en op problemen controleerden. Zoals bij elke codebase die al een paar jaar bestaat en in de loop van de tijd is gegroeid, zijn er mogelijkheden om code te herstructureren en de situatie te verbeteren. Vooral met de overstap naar TypeScript zagen we plaatsen waar een kleine herstructurering van de code ons in staat zou stellen meer op de compiler te leunen en een betere typeveiligheid te krijgen.

Contra-intuïtief is het erg belangrijk om te voorkomen dat u deze veranderingen meteen doorvoert . Het doel van de migratie is om de codebase in TypeScript te krijgen, en tijdens een grote migratie moet u te allen tijde nadenken over het risico dat de software en uw gebruikers kapot gaan. Door de initiële veranderingen minimaal te houden, hebben we dat risico laag gehouden. Nadat het bestand was samengevoegd en naar TypeScript gemigreerd, konden we vervolgwijzigingen aanbrengen om de code te verbeteren en het typesysteem te benutten. Zorg ervoor dat u strikte grenzen stelt aan uw migratie en probeer daarbinnen te blijven.

Het migreren van de tests om onze typedefinities te testen

Nadat we de volledige broncode naar TypeScript hadden gemigreerd, konden we ons concentreren op onze tests . Onze tests hadden een grote dekking, maar waren allemaal in JavaScript geschreven. Dit betekende dat één ding dat ze niet testten onze typedefinities waren. Een van de langetermijndoelen van het project (waar we nog steeds aan werken ) is om standaard typedefinities van hoge kwaliteit te leveren met Puppeteer, maar we hadden geen enkele controle in onze codebase op onze typedefinities.

Door de tests naar TypeScript te migreren (volgens hetzelfde proces, bestand voor bestand gaand), ontdekten we problemen met ons TypeScript die anders aan de gebruikers zouden zijn overgelaten om voor ons te zoeken. Nu dekken onze tests niet alleen al onze functionaliteit, maar fungeren ze ook als kwaliteitscontrole van ons TypeScript !

We hebben al enorm geprofiteerd van TypeScript als technici die aan de Puppeteer-codebase werken. In combinatie met onze sterk verbeterde CI-omgeving heeft het ons in staat gesteld productiever te worden bij het werken aan Puppeteer en TypeScript bugs te laten opvangen die anders in een npm-release zouden zijn terechtgekomen. We zijn verheugd dat TypeScript-definities van hoge kwaliteit worden verzonden, zodat alle ontwikkelaars die Puppeteer gebruiken ook van dit werk kunnen profiteren.

Download de voorbeeldkanalen

Overweeg het gebruik van Chrome Canary , Dev of Beta als uw standaard ontwikkelingsbrowser. Deze preview-kanalen geven u toegang tot de nieuwste DevTools-functies, testen geavanceerde webplatform-API's en ontdekken problemen op uw site voordat uw gebruikers dat doen!

Neem contact op met het Chrome DevTools-team

Gebruik de volgende opties om de nieuwe functies en wijzigingen in het bericht te bespreken, of iets anders gerelateerd aan DevTools.

  • Stuur ons een suggestie of feedback via crbug.com .
  • Rapporteer een DevTools-probleem met behulp van de opties MeerMeer > Help > Rapporteer een DevTools-probleem in DevTools.
  • Tweet op @ChromeDevTools .
  • Laat reacties achter op onze Wat is er nieuw in DevTools YouTube-video's of DevTools Tips YouTube-video's .