Wir im DevTools-Team sind große Fans von TypeScript. So werden in DevTools neuerdings nur noch TypeScript-Code geschrieben und wir befinden uns mitten in einer großen Migration der gesamten Codebasis zu einer TypeScript-Typprüfung. Weitere Informationen zu dieser Migration finden Sie in unserem Vortrag auf dem Chrome Dev Summit 2020. Daher war es sinnvoll, auch die Codebasis von Puppeteer auf TypeScript umzustellen.
Migration planen
Bei der Planung der Migration wollten wir in kleinen Schritten vorankommen. So wird der Migrationsaufwand reduziert, da Sie jeweils nur an einem kleinen Teil des Codes arbeiten. Außerdem sinkt das Risiko. Wenn bei einem der Schritte ein Fehler auftritt, können Sie ihn ganz einfach rückgängig machen. Puppeteer hat viele Nutzer und eine fehlerhafte Version würde für viele von ihnen Probleme verursachen. Daher war es wichtig, das Risiko von fehlerhaften Änderungen so gering wie möglich zu halten.
Außerdem hatten wir das Glück, dass Puppeteer robuste Unit-Tests für alle Funktionen bietet. So konnten wir sicher sein, dass wir bei der Migration keinen Code beschädigten, aber auch, dass wir keine Änderungen an unserer API einführten. Ziel der Migration war es, sie abzuschließen, ohne dass die Puppeteer-Nutzer überhaupt merkten, dass wir migriert waren. Die Tests waren ein wichtiger Bestandteil dieser Strategie. Wenn wir keine gute Testabdeckung gehabt hätten, hätten wir diese hinzugefügt, bevor wir mit der Migration fortgefahren wären.
Codeänderungen ohne Tests sind riskant, aber Änderungen, bei denen Sie ganze Dateien oder die gesamte Codebasis ändern, sind besonders riskant. Bei mechanischen Änderungen kann es leicht passieren, dass ein Schritt übersehen wird. Bei den Tests wurde mehrmals ein Problem festgestellt, das sowohl dem Implementierer als auch dem Prüfer entgangen war.
Eine Sache, in die wir vorab Zeit investiert haben, war unsere Continuous Integration (CI)-Einrichtung. Wir haben festgestellt, dass CI-Ausführungen für Pull-Requests unzuverlässig waren und oft fehlgeschlagen sind. Das passierte so oft, dass wir uns angewöhnt hatten, unsere CI zu ignorieren und die Pull-Requests trotzdem zusammenzuführen, da wir davon ausgingen, dass der Fehler ein einmaliges Problem bei der CI und kein Problem in Puppeteer war.
Nach einigen allgemeinen Wartungsarbeiten und der Behebung einiger regelmäßiger Testfehler konnten wir den Zustand des Builds so verbessern, dass er viel häufiger bestanden wurde. So konnten wir uns auf die CI verlassen und wussten, dass ein Fehler auf ein tatsächliches Problem hindeutete. Diese Arbeit ist nicht glamourös und es ist frustrierend, endlose CI-Ausführungen zu beobachten. Angesichts der Anzahl der Pull-Requests, die durch die Migration ausgelöst wurden, war es jedoch wichtig, dass unsere Testsuite zuverlässig funktioniert.
Eine Datei auswählen und landen
Zu diesem Zeitpunkt war unsere Migration bereit und wir hatten einen robusten CI-Server mit vielen Tests, die uns den Rücken freihielten. Anstatt eine beliebige Datei zu verwenden, haben wir eine kleine Datei zur Migration ausgewählt. Das ist eine nützliche Übung, da Sie so den geplanten Prozess validieren können, den Sie gerade durchführen. Wenn es bei dieser Datei funktioniert, ist Ihr Ansatz gültig. Andernfalls können Sie noch einmal von vorn beginnen.
Außerdem wurde Datei für Datei vorgegangen und es gab regelmäßige Puppeteer-Releases, sodass nicht alle Änderungen in derselben npm-Version veröffentlicht wurden. So konnte das Risiko gesenkt werden. Wir haben DeviceDescriptors.js
als erste Datei ausgewählt, da es sich um eine der einfachsten Dateien in der Codebasis handelt. Es kann etwas enttäuschend sein, all diese Vorbereitungsarbeit zu leisten und nur eine so kleine Änderung vorzunehmen. Das Ziel besteht jedoch nicht darin, sofort große Änderungen vorzunehmen, sondern vorsichtig und methodisch Datei für Datei vorzugehen. Die Zeit, die Sie mit der Validierung des Ansatzes verbringen, spart Ihnen später bei der Migration Zeit, wenn Sie auf diese komplizierteren Dateien stoßen.
Muster beweisen und wiederholen
Glücklicherweise wurde die Änderung an DeviceDescriptors.js
in die Codebasis übernommen und der Plan funktionierte wie erhofft. Jetzt sind Sie bereit, sich an die Arbeit zu machen. Genau das haben wir getan. Mit einem GitHub-Label können Sie alle Pull-Anfragen gruppieren. Das ist sehr hilfreich, um den Fortschritt im Blick zu behalten.
Jetzt migrieren und später optimieren
Für jede einzelne JavaScript-Datei haben wir folgende Schritte ausgeführt:
- Benennen Sie die Datei von
.js
in.ts
um. - Führen Sie den TypeScript-Compiler aus.
- Beheben Sie alle Probleme.
- Erstellen Sie die Pull-Anfrage.
Der Großteil der Arbeit in diesen ersten Pull-Requests bestand darin, TypeScript-Schnittstellen für vorhandene Datenstrukturen zu extrahieren. Beim ersten Pull-Request, mit dem DeviceDescriptors.js
migriert wurde, sah der Code so aus:
module.exports = [
{
name: 'Pixel 4',
… // Other fields omitted to save space
},
…
]
und wurde zu:
interface Device {
name: string,
…
}
const devices: Device[] = [{name: 'Pixel 4', …}, …]
module.exports = devices;
Im Rahmen dieses Prozesses haben wir jede Zeile der Codebasis auf Probleme überprüft. Wie bei jeder Codebasis, die seit einigen Jahren besteht und im Laufe der Zeit gewachsen ist, gibt es Bereiche, in denen Code umgeschrieben und die Situation verbessert werden kann. Insbesondere bei der Umstellung auf TypeScript haben wir Stellen gefunden, an denen wir durch eine leichte Umstrukturierung des Codes den Compiler stärker nutzen und die Typsicherheit verbessern konnten.
Es ist zwar kontraintuitiv, aber es ist wirklich wichtig, diese Änderungen nicht sofort vorzunehmen. Ziel der Migration ist es, die Codebasis in TypeScript zu konvertieren. Bei einer großen Migration sollten Sie immer das Risiko im Auge behalten, dass die Software und Ihre Nutzer dadurch beeinträchtigt werden. Durch die Begrenzung der ersten Änderungen auf ein Minimum haben wir dieses Risiko minimiert. Nachdem die Datei zusammengeführt und zu TypeScript migriert wurde, konnten wir weitere Änderungen vornehmen, um den Code zu verbessern und das Typsystem zu nutzen. Legen Sie strenge Grenzen für die Migration fest und versuchen Sie, diese einzuhalten.
Migration der Tests zum Testen unserer Typdefinitionen
Nachdem der gesamte Quellcode zu TypeScript migriert war, konnten wir uns auf unsere Tests konzentrieren. Unsere Tests hatten eine gute Abdeckung, wurden aber alle in JavaScript geschrieben. Das bedeutet, dass unsere Typdefinitionen nicht getestet wurden. Eines der langfristigen Ziele des Projekts (an dem wir noch arbeiten) ist es, hochwertige Typdefinitionen direkt mit Puppeteer ausliefern zu können. In unserer Codebasis gab es jedoch keine Prüfungen für unsere Typdefinitionen.
Bei der Migration der Tests zu TypeScript (demselben Verfahren folgend, Datei für Datei) haben wir Probleme mit unserem TypeScript gefunden, die sonst von den Nutzern gefunden worden wären. Unsere Tests decken jetzt nicht nur alle Funktionen ab, sondern dienen auch als Qualitätscheck für unser TypeScript.
Als Entwickler, die an der Puppeteer-Codebasis arbeiten, haben wir bereits enorm von TypeScript profitiert. In Kombination mit unserer stark verbesserten CI-Umgebung konnten wir bei der Arbeit an Puppeteer produktiver werden und mit TypeScript Fehler erkennen, die sonst in eine npm-Version gelangt wären. Wir freuen uns, hochwertige TypeScript-Definitionen bereitstellen zu können, damit alle Entwickler, die Puppeteer verwenden, von dieser Arbeit profitieren können.
Vorschaukanäle herunterladen
Verwenden Sie als Standard-Entwicklungsbrowser Chrome Canary, Chrome Dev oder Chrome Beta. Diese Vorabversionen bieten Ihnen Zugriff auf die neuesten DevTools-Funktionen, ermöglichen es Ihnen, innovative Webplattform-APIs zu testen, und helfen Ihnen, Probleme auf Ihrer Website zu finden, bevor Ihre Nutzer sie bemerken.
Chrome-Entwicklertools-Team kontaktieren
Mit den folgenden Optionen können Sie über neue Funktionen, Updates oder andere Themen im Zusammenhang mit den DevTools sprechen.
- Senden Sie uns Feedback und Funktionsanfragen unter crbug.com.
- Melden Sie ein DevTools-Problem über das Dreipunkt-Menü Weitere Optionen > Hilfe > DevTools-Problem melden.
- Tweeten Sie an @ChromeDevTools.
- Hinterlassen Sie Kommentare unter den YouTube-Videos zu den Neuigkeiten in den DevTools oder den YouTube-Videos mit Tipps zu den DevTools.