Puppeteer zu TypeScript migrieren

Franklin
Jack Franklin

Wir sind große Fans von TypeScript im DevTools-Team – so sehr, dass neuer Code in den Entwicklertools darin erstellt wird und wir uns mitten in einer großen Migration der gesamten Codebasis zur Typprüfung durch TypeScript befinden. Weitere Informationen zu dieser Migration findet ihr in unserem Vortrag auf dem Chrome Dev Summit 2020. Daher war es sinnvoll, auch die Migration der Puppeteer-Codebasis zu TypeScript zu prüfen.

Migration planen

Bei der Planung der Migration wollten wir in kleinen Schritten Fortschritte erzielen können. So wird der Aufwand für die Migration gering gehalten – Sie arbeiten immer nur an einem kleinen Teil des Codes – und gleichzeitig das Risiko gering. Sollte bei einem der Schritte etwas schiefgehen, können Sie es ganz einfach rückgängig machen. Puppeteer hat viele Nutzer und ein defekter Release würde für viele Probleme verursachen. Daher war es wichtig, dass wir das Risiko von funktionsgefährdenden Änderungen auf ein Minimum beschränken.

Außerdem haben wir uns erfreut, dass Puppeteer über eine robuste Reihe von Einheitentests verfügt, die alle Funktionen abdecken. Das bedeutete, dass wir sicher sein konnten, dass wir während der Migration keinen Codefehler einbrachten, aber auch keine Änderungen an unserer API einführten. Das Ziel der Migration bestand darin, die Migration abzuschließen, ohne dass Puppeteer-Nutzern überhaupt bewusst wurde, dass wir migriert waren, und die Tests waren ein wichtiger Bestandteil dieser Strategie. Hätten wir keine gute Testabdeckung gehabt, hätten wir diese hinzugefügt, bevor wir mit der Migration fortfahren.

Jede Codeänderung ohne Tests ist riskant. Besonders riskant sind jedoch Änderungen, bei denen Sie ganze Dateien oder die gesamte Codebasis bearbeiten. Wenn mechanische Änderungen vorgenommen werden, kann es leicht passieren, dass ein Schritt ausgelassen wird. In den Tests wurde außerdem ein Problem festgestellt, das sowohl den Implementierer als auch den Prüfer überwunden hat.

Wir haben vorab Zeit in die Einrichtung von Continuous Integration (CI) investiert. Wir haben festgestellt, dass CI-Ausführungen für Pull-Anfragen instabil waren und häufig fehlgeschlagen sind. Das geschah so oft, dass wir uns zur Gewohnheit gemacht hatten, unsere CI zu ignorieren und die Pull-Anfragen trotzdem zusammenzuführen, da wir davon ausgingen, dass der Fehler ein einmaliges Problem auf CI und kein Problem in Puppeteer war.

Nach einer gewissen allgemeinen Wartung und einer gewissen Zeit zur Behebung einiger regelmäßiger Test-Flakes haben wir einen wesentlich konsistenteren Status erreicht. So können wir CI abhören und wissen, dass ein Fehler auf ein tatsächliches Problem hindeutet. Diese Arbeit ist nicht glamourös und es ist frustrierend, endlose CI-Ausführungen zu beobachten. Es war jedoch von entscheidender Bedeutung, dass unsere Testsuite zuverlässig ausgeführt wird, da die Anzahl der von der Migration aufgewendeten Pull-Anfragen sehr hoch war.

Eine Datei auswählen und bereitstellen

Zu diesem Zeitpunkt war unsere Migration betriebsbereit und wir hatten einen robusten CI-Server voller Tests, um uns auf den Rücken zu schauen. Anstatt uns mit einer beliebigen Datei zu befassen, haben wir gezielt eine kleine Datei für die Migration ausgewählt. Dies ist eine nützliche Übung, da Sie damit den geplanten Prozess validieren können. Wenn sie mit dieser Datei funktioniert, ist Ihr Ansatz gültig. Falls nicht, können Sie noch einmal von vorn beginnen.

Außerdem wurde das Risiko minimiert, indem Datei für Datei verwendet wurde (und mit regulären Puppeteer-Releases, sodass nicht alle Änderungen in derselben npm-Version übermittelt wurden). Wir haben DeviceDescriptors.js als erste Datei ausgewählt, da dies eine der einfachsten Dateien in der Codebasis war. Es kann etwas erdrückend wirken, all diese Vorbereitungsarbeit und eine so kleine Änderung in Angriff zu nehmen, aber das Ziel besteht nicht darin, große Änderungen sofort vorzunehmen, sondern vorsichtig und systematisch Datei für Datei vorzunehmen. Der Zeitaufwand für die Validierung des Ansatzes spart später bei der Migration definitiv Zeit, wenn Sie diese komplizierteren Dateien benötigen.

Muster beweisen und wiederholen

Glücklicherweise wurde die Änderung an DeviceDescriptors.js erfolgreich in die Codebasis übernommen und der Plan funktionierte so, wie wir gehofft hatten. Jetzt können Sie loslegen und loslegen. Genau das haben wir getan. Die Verwendung eines GitHub-Labels ist eine tolle Möglichkeit, alle Pull-Anfragen zu gruppieren, und das hat sich als nützlich erwiesen, um den Fortschritt zu verfolgen.

Daten migrieren und später verbessern

Für jede einzelne JavaScript-Datei ging unser Prozess wie folgt vor:

  1. Benennen Sie die Datei um von .js in .ts.
  2. Führen Sie den TypeScript-Compiler aus.
  3. Beheben Sie alle Probleme.
  4. 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. Im Fall der ersten Pull-Anfrage, die DeviceDescriptors.js migriert hat, über die wir bereits gesprochen haben, stammte der Code von:

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;

Als Teil dieses Prozesses mussten wir jede Zeile der Codebasis auf Probleme prüfen. Wie bei jeder Codebasis, die schon vor einigen Jahren besteht und im Laufe der Zeit gewachsen ist, gibt es Bereiche, in denen Code refaktoriert und die Situation verbessert werden kann. Besonders beim Wechsel zu TypeScript ergaben sich Stellen, an denen eine leichte Umstrukturierung des Codes es uns ermöglichte, uns mehr auf den Compiler zu stützen und eine bessere Schreibsicherheit zu erzielen.

Gegen Intuitivität ist es wirklich wichtig, diese Änderungen sofort vorzunehmen. Das Ziel der Migration ist es, die Codebasis in TypeScript zu übertragen. Während einer großen Migration sollten Sie stets über das Risiko von Fehlern bei der Software und Ihren Nutzern nachdenken. Da die anfänglichen Änderungen minimal waren, hielten wir dieses Risiko gering. Nachdem die Datei zusammengeführt und zu TypeScript migriert wurde, konnten wir weitere Änderungen vornehmen, um den Code zur Nutzung des Typsystems zu verbessern. Legen Sie für die Migration strenge Grenzen fest und halten Sie diese ein.

Tests zum Testen unserer Typdefinitionen migrieren

Nachdem der gesamte Quellcode zu TypeScript migriert wurde, können wir uns auf unsere Tests konzentrieren. Unsere Tests hatten zwar eine sehr gute Abdeckung, wurden aber alle in JavaScript geschrieben. Dies bedeutete, dass nicht unsere Typdefinitionen getestet wurden. Eines der langfristigen Ziele des Projekts, an dem wir noch arbeiten, besteht darin, mit Puppeteer qualitativ hochwertige Typdefinitionen bereitzustellen, aber wir hatten in unserer Codebasis keine Überprüfungen zu unseren Typdefinitionen.

Durch die Migration der Tests zu TypeScript haben wir im gleichen Prozess und Datei für Datei Probleme festgestellt, die die Nutzer sonst für uns finden müssten. Unsere Tests decken jetzt nicht nur alle unsere Funktionen ab, sondern dienen auch einer Qualitätsprüfung unseres TypeScript.

Wir haben bereits enorm von TypeScript als Entwickler profitieren, die an der Puppeteer-Codebasis arbeiten. In Kombination mit unserer stark verbesserten CI-Umgebung konnten wir bei der Arbeit an Puppeteer produktiver arbeiten und TypeScript-Fehler abfangen, die sonst in einen npm-Release aufgenommen worden wären. Wir freuen uns über die Bereitstellung hochwertiger TypeScript-Definitionen, damit alle Entwickler, die Puppeteer verwenden, ebenfalls von dieser Arbeit profitieren können.

Vorschaukanäle herunterladen

Du kannst Chrome Canary, Dev oder Beta als Standardbrowser für die Entwicklung verwenden. Mit diesen Vorschaukanälen erhalten Sie Zugriff auf die neuesten Funktionen der Entwicklertools, können bahnbrechende Webplattform-APIs testen und Probleme auf Ihrer Website erkennen, noch bevor Ihre Nutzer dies tun.

Chrome-Entwicklertools-Team kontaktieren

Verwende die folgenden Optionen, um die neuen Funktionen und Änderungen im Beitrag oder andere Themen im Zusammenhang mit den Entwicklertools zu besprechen.

  • Sende uns über crbug.com einen Vorschlag oder Feedback.
  • Wenn du ein Problem mit den Entwicklertools melden möchtest, klicke in den Entwicklertools auf Weitere Optionen   Mehr   > Hilfe > Probleme mit Entwicklertools melden.
  • Senden Sie einen Tweet an @ChromeDevTools.
  • Hinterlasse Kommentare unter YouTube-Videos oder YouTube-Videos mit Tipps zu DevTools.