Im DevTools-Team sind wir große Fans von TypeScript. Inzwischen wird neuer Code in DevTools erstellt und wir befinden uns mitten in einer großen Migration der gesamten Codebasis zu einer Typprüfung durch TypeScript. 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 Aufwand für die Migration gering gehalten, da Sie jederzeit nur an einem kleinen Teil des Codes arbeiten. Außerdem wird das Risiko minimiert. Sollten bei einem der Schritte irgendwelche Probleme auftreten, können Sie es einfach rückgängig machen. Puppeteer hat viele Nutzer und ein defektes Release würde bei vielen von ihnen Probleme verursachen, daher war es wichtig, dass wir das Risiko von funktionsgefährdenden Änderungen auf ein Minimum reduzieren.
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 es keine gute Testabdeckung gegeben hätte, hätten wir diese vor der Migration hinzugefügt.
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 bereitstellen
Zu diesem Zeitpunkt stand unsere Migration bereit und wir hatten einen robusten CI-Server voller Tests, den wir überwachen konnten. 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 mit dieser Datei funktioniert, ist Ihr Ansatz gültig. Falls nicht, können Sie zum Zeichenbrett zurückkehren.
Außerdem wurde das Risiko dateiübergreifend verringert (und mit regulären Puppeteer-Releases, sodass nicht alle Änderungen in der gleichen npm-Version verschickt wurden). 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.
Bei diesen ersten Pull-Anfragen bestand der Großteil der Arbeit 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;
Dabei haben wir jede Zeile der Codebasis überprüft und auf Probleme geprüft. Wie bei jeder Codebasis, die schon einige Jahre alt ist 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 Typensicherheit verbessern konnten.
Im Gegenteil: 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. Indem wir die anfänglichen Änderungen minimal halten, haben wir dieses Risiko gering gehalten. 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 wiesen eine hohe Abdeckung auf, waren jedoch alle in JavaScript geschrieben. Deshalb wurden unsere Typdefinitionen nicht getestet. 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 Zugriff auf die neuesten DevTools-Funktionen, ermöglichen den Test moderner Webplattform-APIs 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.