Memindahkan Puppeteer ke TypeScript

Kami adalah penggemar berat TypeScript di tim DevTools—begitu banyak kode baru di DevTools yang ditulis di dalamnya dan kami berada di tengah migrasi besar dari seluruh codebase untuk diperiksa jenisnya oleh TypeScript. Anda dapat mengetahui lebih lanjut tentang migrasi tersebut dalam diskusi kami di Chrome Dev Summit 2020. Oleh karena itu, sangat masuk akal untuk memigrasikan codebase Puppeteer ke TypeScript.

Merencanakan migrasi

Saat merencanakan cara melakukan migrasi, kami ingin dapat membuat progres dalam langkah-langkah kecil. Hal ini membuat overhead migrasi tetap rendah—Anda hanya mengerjakan sebagian kecil kode kapan saja—dan juga menekan risikonya. Jika terjadi kesalahan pada salah satu langkah, Anda dapat dengan mudah mengembalikannya. Puppeteer memiliki banyak pengguna dan rilis yang rusak akan menyebabkan masalah bagi banyak pengguna, jadi sangat penting untuk meminimalkan risiko perubahan yang dapat menyebabkan gangguan.

Kami juga beruntung bahwa Puppeteer memiliki serangkaian pengujian unit yang andal yang mencakup semua fungsinya. Hal ini berarti kami dapat yakin bahwa kami tidak melanggar kode saat melakukan migrasi, tetapi juga bahwa kami tidak memperkenalkan perubahan pada API. Tujuan migrasi ini adalah untuk menyelesaikannya tanpa ada pengguna Puppeteer yang menyadari bahwa kami telah melakukan migrasi, dan pengujian tersebut merupakan bagian penting dari strategi tersebut. Jika kami tidak memiliki cakupan pengujian yang baik, kami harus menambahkannya sebelum melanjutkan migrasi.

Melakukan perubahan kode apa pun tanpa pengujian berisiko, tetapi perubahan saat Anda menyentuh seluruh file atau keseluruhan codebase sangat berisiko. Saat melakukan perubahan mekanis, sangat mudah melewatkan satu langkah, dan pada beberapa kesempatan pengujian menemukan masalah yang telah melewati pelaksana dan peninjau.

Satu hal yang kami lakukan menginvestasikan waktu di awal adalah penyiapan Continuous Integration (CI). Kami melihat bahwa CI yang dijalankan terhadap permintaan pull tidak stabil dan sering gagal. Hal ini sering terjadi sehingga kami terbiasa mengabaikan CI dan menggabungkan permintaan pull, dengan asumsi bahwa kegagalan adalah masalah satu kali di CI, bukan masalah di Puppeteer.

Setelah melakukan pemeliharaan umum dan waktu khusus untuk memperbaiki beberapa serpihan pengujian reguler, kami melewatinya menjadi lebih konsisten, sehingga kami dapat mendengarkan CI dan mengetahui bahwa kegagalan menunjukkan masalah yang sebenarnya. Pekerjaan ini tidak terlalu glamor, dan menjengkelkan ketika melihat CI yang terus-menerus berjalan, tetapi kami harus menjalankan rangkaian pengujian yang berjalan dengan andal mengingat jumlah permintaan pull yang dihasilkan oleh migrasi.

Pilih dan letakkan satu file

Pada tahap ini, kami telah menyiapkan migrasi dan server CI yang tangguh dan penuh dengan pengujian untuk memantau kondisi di sini. Alih-alih mempelajari file arbitrer apa pun, kami sengaja memilih file kecil untuk dimigrasikan. Ini adalah latihan yang berguna karena memungkinkan Anda memvalidasi proses terencana yang akan Anda lakukan. Jika berhasil pada file ini, berarti pendekatan Anda valid; jika tidak, Anda dapat kembali ke papan gambar.

Selain itu, pergi file demi file (dan dengan rilis Puppeteer reguler, sehingga semua perubahan tidak dikirimkan dalam versi npm yang sama) menjaga risiko tetap rendah. Kami memilih DeviceDescriptors.js sebagai file pertama, karena ini adalah salah satu file paling mudah di codebase. Melakukan semua tugas persiapan ini dan melakukan perubahan sekecil itu mungkin terasa sedikit merepotkan, tetapi tujuannya bukan untuk membuat perubahan besar dengan segera, tetapi untuk melanjutkan dengan hati-hati dan secara metodis file per file. Waktu yang dihabiskan untuk memvalidasi pendekatan benar-benar menghemat waktu di kemudian hari dalam migrasi ketika Anda menemukan file yang lebih rumit tersebut.

Buktikan polanya dan ulangi

Untungnya, perubahan pada DeviceDescriptors.js berhasil diterapkan ke codebase, dan rencana tersebut berfungsi seperti yang kami harapkan. Di titik ini, Anda siap untuk melanjutkan, itulah yang kami lakukan. Menggunakan label GitHub adalah cara yang sangat bagus untuk mengelompokkan semua permintaan pull bersama-sama, dan kami merasa hal ini berguna untuk melacak progres.

Lakukan migrasi dan tingkatkan kualitas ini nanti

Untuk setiap file JavaScript, proses kami adalah:

  1. Ganti nama file dari .js menjadi .ts.
  2. Jalankan compiler TypeScript.
  3. Perbaiki semua masalah.
  4. Buat permintaan pull.

Sebagian besar tugas dalam permintaan pull awal ini adalah mengekstrak antarmuka TypeScript untuk struktur data yang ada. Dalam kasus permintaan pull pertama yang memigrasikan DeviceDescriptors.js yang telah kita bahas sebelumnya, kodenya berasal dari:

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

Dan menjadi:

interface Device {
  name: string,
  …
}

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

module.exports = devices;

Sebagai bagian dari proses ini, kami harus menyelesaikan setiap baris pemeriksaan codebase untuk menemukan masalah. Seperti codebase yang telah ada selama beberapa tahun dan terus berkembang dari waktu ke waktu, ada area peluang untuk memfaktorkan ulang kode dan memperbaiki situasi. Terutama saat beralih ke TypeScript, kami melihat tempat-tempat di mana sedikit restrukturisasi kode akan memungkinkan kita untuk lebih mengandalkan compiler dan mendapatkan keamanan jenis yang lebih baik.

Secara kontra-intuisi, sangat penting untuk tidak langsung melakukan perubahan ini. Tujuan migrasi ini adalah memasukkan codebase ke TypeScript, dan setiap saat selama migrasi besar, Anda harus memikirkan risiko menyebabkan kerusakan pada software dan pengguna Anda. Dengan meminimalkan perubahan di awal, kita menjaga risiko tersebut tetap rendah. Setelah file digabungkan dan dimigrasikan ke TypeScript, kita dapat membuat perubahan lanjutan untuk meningkatkan kualitas kode agar dapat memanfaatkan sistem jenis. Pastikan Anda menetapkan batasan yang ketat untuk migrasi dan mencoba untuk tidak mematuhinya.

Memigrasikan pengujian untuk menguji definisi jenis kami

Setelah seluruh kode sumber dimigrasikan ke TypeScript, kita dapat mengalihkan fokus ke pengujian. Pengujian kami memiliki cakupan yang sangat baik, tetapi semuanya ditulis dalam JavaScript. Ini berarti satu hal yang tidak mereka uji adalah definisi jenis. Salah satu tujuan jangka panjang project ini (yang masih kami kerjakan) adalah menghadirkan definisi jenis berkualitas tinggi secara langsung dengan Puppeteer, tetapi kami tidak memiliki pemeriksaan apa pun di codebase tentang definisi jenis.

Dengan memigrasikan pengujian ke TypeScript (mengikuti proses yang sama, membuka file demi file), kami menemukan masalah pada TypeScript yang seharusnya diserahkan kepada pengguna untuk menemukannya. Sekarang pengujian kami tidak hanya mencakup semua fungsi, tetapi juga berfungsi sebagai pemeriksaan kualitas TypeScript kami.

Kami telah mendapatkan banyak manfaat dari TypeScript sebagai engineer yang mengerjakan codebase Puppeteer. Bersama dengan lingkungan CI kami yang jauh lebih baik, hal ini memungkinkan kami menjadi lebih produktif saat mengerjakan Puppeteer dan membuat TypeScript menangkap bug yang seharusnya berhasil dalam rilis npm. Kami sangat senang karena definisi TypeScript berkualitas tinggi dikirimkan agar semua developer yang menggunakan Puppeteer dapat memperoleh manfaat dari upaya ini.

Mendownload saluran pratinjau

Pertimbangkan untuk menggunakan Chrome Canary, Dev, atau Beta sebagai browser pengembangan default Anda. Saluran pratinjau ini memberi Anda akses ke fitur DevTools terbaru, menguji API platform web tercanggih, dan menemukan masalah di situs Anda sebelum pengguna melakukannya.

Menghubungi tim Chrome DevTools

Gunakan opsi berikut untuk membahas fitur dan perubahan baru di postingan ini, atau hal lain yang terkait dengan DevTools.

  • Kirim saran atau masukan kepada kami melalui crbug.com.
  • Laporkan masalah DevTools menggunakan Opsi lainnya   Lainnya   > Bantuan > Laporkan masalah DevTools di DevTools.
  • Tweet di @ChromeDevTools.
  • Tuliskan komentar di video YouTube Yang baru di DevTools atau video YouTube di DevTools.