Migrazione di Puppeteer a TypeScript

Jack Franklin
Jack Franklin

Nel team DevTools piace molto TypeScript, al punto che viene creato il nuovo codice in DevTools e ci troviamo nel bel mezzo di una grande migrazione dell'intero codebase al controllo di tipo da parte di TypeScript. Puoi scoprire di più su questa migrazione nella nostra presentazione al Chrome Dev Summit 2020. Pertanto, era perfettamente logico esaminare anche la migrazione del codebase di Pupeteer a TypeScript.

Pianificazione della migrazione

Quando abbiamo pianificato la migrazione, volevamo essere in grado di fare progressi in piccoli passaggi. In questo modo puoi ridurre il carico di lavoro della migrazione, perché stai lavorando solo su una piccola parte del codice in qualsiasi momento, e anche i rischi sono ridotti. In caso di problemi con uno dei passaggi, puoi facilmente ripristinarli. Puppeteer ha molti utenti e una release non funzionante avrebbe causato problemi a molti di loro, quindi era fondamentale ridurre al minimo il rischio di interrompere le modifiche.

Abbiamo anche avuto la fortuna che Puppeteer ha implementato una solida serie di test delle unità che coprono tutte le sue funzionalità. Questo significava poter essere certi che non stavamo violando il codice durante la migrazione, ma anche che non stavamo apportando modifiche alla nostra API. L'obiettivo della migrazione era completarla senza che gli utenti di Puppeteer si rendessero nemmeno conto della migrazione e i test erano una parte vitale di questa strategia. Se non avessimo avuto una buona copertura di test, lo avremmo aggiunto prima di continuare la migrazione.

Eseguire qualsiasi modifica al codice senza test è rischioso, ma le modifiche in cui si toccano interi file o l'intero codebase sono particolarmente rischiose. Quando si apportano modifiche meccaniche, è facile perdere un passaggio e, in più occasioni, i test individuano un problema che è sfuggito sia all'implementatore sia al revisore.

Una cosa su cui abbiamo investito tempo in anticipo è stata la nostra configurazione dell'integrazione continua (CI). Abbiamo notato che le esecuzioni della CI contro le richieste di pull erano instabili e spesso non riuscivano. Questo accadeva così spesso che avevamo l'abitudine di ignorare la nostra CI e di unire comunque le richieste di pull, supponendo che l'errore fosse un problema una tantum su CI piuttosto che un problema in Puppeteer.

Dopo un po' di manutenzione generale e un po' di tempo dedicato alla correzione di alcuni flake di prova, lo abbiamo riportato in uno stato di passaggio molto più regolare, in modo da poter ascoltare la CI e sapere che un guasto indicava un problema reale. Questo lavoro non è accattivante ed è frustrante guardare innumerevoli esecuzioni di CI, ma era fondamentale che la nostra suite di test venisse eseguita in modo affidabile dato il numero di richieste di pull che la migrazione gli stava inviando.

Scegli e scarica un file

A questo punto, la migrazione era pronta e avevamo un server CI solido pieno di test su cui ci si affidava. Anziché esaminare qualsiasi file arbitrario, abbiamo volutamente scelto di proposito un file di piccole dimensioni di cui eseguire la migrazione. Questo è un esercizio utile perché ti consente di convalidare il processo pianificato che stai per intraprendere. Se funziona su questo file, il tuo approccio è valido; in caso contrario, puoi tornare al tavolo da disegno.

Inoltre, passare file per file (e con le normali release Puppeteer, quindi tutte le modifiche non venivano fornite nella stessa versione npm) ha ridotto il rischio. Abbiamo scelto DeviceDescriptors.js come primo file, perché era uno dei file più semplici del codebase. Fare tutto questo lavoro di preparazione e ottenere una modifica così piccola può sembrare un po' deludente, ma l'obiettivo non è apportare modifiche enormi all'istante, ma procedere con cautela e metodicamente file per file. Il tempo dedicato alla convalida dell'approccio consente sicuramente di risparmiare tempo in un secondo momento della migrazione, quando accedi ai file più complessi.

Dimostra la sequenza e ripeti

Fortunatamente, la modifica a DeviceDescriptors.js è stata introdotta correttamente nel codebase e il piano ha funzionato come sperato. A questo punto, sei pronto per iniziare, che è esattamente ciò che abbiamo fatto. Usare un'etichetta GitHub è un modo davvero bello per raggruppare tutte le richieste di pull e lo abbiamo trovato utile per monitorare i progressi.

Esegui la migrazione e migliorala in un secondo momento

Per ogni singolo file JavaScript il nostro processo era:

  1. Rinomina il file da .js a .ts.
  2. Esegui il compilatore TypeScript.
  3. Risolvi eventuali problemi.
  4. Crea la richiesta di pull.

La maggior parte del lavoro in queste richieste di pull iniziali riguardava l'estrazione delle interfacce TypeScript per le strutture di dati esistenti. Nel caso della prima richiesta di pull che ha eseguito la migrazione di DeviceDescriptors.js di cui abbiamo parlato in precedenza, il codice è passato da:

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

E poi:

interface Device {
  name: string,
  …
}

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

module.exports = devices;

Nell'ambito di questo processo, abbiamo lavorato su ogni riga del codebase per verificare la presenza di problemi. Come per qualsiasi codebase che è stato da qualche anno e cresciuto nel tempo, ci sono aree di opportunità per eseguire il refactoring del codice e migliorare la situazione. In particolare con il passaggio a TypeScript, abbiamo visto dei punti in cui una leggera ristrutturazione del codice ci avrebbe consentito di affidarci maggiormente al compilatore e di ottenere una maggiore sicurezza del tipo.

controintuitivamente, è molto importante resistere ad apportare queste modifiche immediatamente. L'obiettivo della migrazione è portare il codebase a TypeScript e, in qualsiasi momento durante una migrazione di grandi dimensioni, dovresti pensare al rischio di causare interruzioni del software e dei tuoi utenti. Mantenendo al minimo le modifiche iniziali, questo rischio è stato ridotto. Dopo aver unito il file ed eseguito la migrazione a TypeScript, abbiamo potuto apportare ulteriori modifiche per migliorare il codice e utilizzare il sistema di tipi. Assicurati di impostare limiti rigorosi per la migrazione e cerca di rispettarli.

Migrazione dei test per testare le definizioni dei tipi

Una volta eseguita la migrazione dell'intero codice sorgente a TypeScript, abbiamo potuto concentrarci sui test. I nostri test hanno avuto un'ottima copertura, ma sono stati tutti scritti in JavaScript. Ciò significa che una cosa che non hanno testato erano le nostre definizioni dei tipi. Uno degli obiettivi a lungo termine del progetto (a cui stiamo ancora lavorando) è fornire immediatamente definizioni di alta qualità con Puppeteer, ma non abbiamo avuto controlli nel nostro codebase per le definizioni dei tipi.

Eseguendo la migrazione dei test a TypeScript (seguendo lo stesso processo file per file), abbiamo riscontrato problemi con TypeScript che altrimenti sarebbero stati lasciati agli utenti. Ora i nostri test non solo coprono tutte le nostre funzionalità, ma fungono anche da controllo di qualità del nostro TypeScript.

Abbiamo già enormemente beneficiato di TypeScript in qualità di ingegneri che lavorano nel codebase Puppeteer. Insieme al nostro ambiente CI, molto migliorato, ci ha consentito di essere più produttivi quando lavoriamo su Puppeteer e di avere TypeScript per rilevare i bug che altrimenti sarebbero stati trasformati in una release npm. Siamo entusiasti di ricevere definizioni TypeScript di alta qualità per consentire anche a tutti gli sviluppatori che utilizzano Puppeteer di trarre vantaggio da questo lavoro.

Scaricare i canali in anteprima

Prendi in considerazione l'utilizzo di Chrome Canary, Dev o Beta come browser di sviluppo predefinito. Questi canali in anteprima ti consentono di accedere alle ultime funzionalità DevTools, testare le API delle piattaforme web all'avanguardia e individuare eventuali problemi sul tuo sito prima che lo facciano gli utenti.

Contattare il team di Chrome DevTools

Utilizza le seguenti opzioni per discutere delle nuove funzionalità e modifiche nel post o qualsiasi altra informazione relativa a DevTools.

  • Inviaci un suggerimento o un feedback tramite crbug.com.
  • Segnala un problema di DevTools utilizzando Altre opzioni   Altre   > Guida > Segnala i problemi di DevTools in DevTools.
  • Tweet all'indirizzo @ChromeDevTools.
  • Lascia commenti sui video di YouTube o sui suggerimenti di DevTools sui video di YouTube di DevTools.