將 Puppeteer 遷移至 TypeScript

傑克.富蘭克林 (Jack Franklin)
Jack Franklin

我們是 DevTools 團隊的 TypeScript 大量粉絲,因此許多人都編寫了開發人員工具中的新程式碼,而我們正著手遷移整個程式碼集,以便由 TypeScript 進行類型檢查。如要進一步瞭解這項遷移作業,請觀看 2020 年 Chrome 開發人員高峰會的講座。因此,您也可以考慮將 Puppeteer 的程式碼集遷移至 TypeScript。

規劃遷移作業

規劃遷移方式時,我們希望能夠從微小步驟取得進展。這樣可以減少遷移作業的負擔 (您隨時可以只處理一小部分程式碼),並降低風險。如果其中一個步驟發生問題,你也能輕鬆還原。Puppeteer 有許多使用者,而由於版本損毀,對許多使用者會造成問題,因此必須將破壞性變更的風險降到最低。

此外,我們也要幸運的是,Puppeteer 已通過一系列完善的單元測試,涵蓋了所有功能。這表示我們確實不會在遷移過程中破壞程式碼,但也沒有對 API 進行變更。我們的目標是完成遷移的目標,避免任何 Puppeteer 使用者知道我們已完成遷移,而測試是該策略的重要一環。如果測試涵蓋範圍不夠完善,我們會在繼續遷移前新增這項資訊。

如果在未經測試的情況下執行任何程式碼變更是有風險的,但您對整個檔案或整個程式碼集進行的變更,會特別有風險。變更機制時,很容易錯過某個步驟,而且在多種情況下,測試發現了問題,無法同時從執行者和審查人員排除。

我們預先投入了大量時間,就是持續整合 (CI) 設定。我們發現提取要求中的持續整合作業發生問題,且經常失敗。這種情況經常發生,我們經常會為了忽略持續整合並合併提取要求,假設失敗是 CI 中的一次性問題,而不是 Puppeteer 的問題。

在進行一般維護及專門修正一些定期測試迴圈後,我們實現了更一致的狀態通過,因此能夠監聽 CI,並確定失敗的原因是實際問題。這並不完美,而且檢視無盡的 CI 執行作業會讓您感到不悅,但由於遷移作業擲回的提取要求數量,測試套件能穩定執行是很重要的。

挑選一個檔案並放置

目前,我們已準備好進行遷移作業,擁有完善的持續整合伺服器,等待測試作業完成。我們特意選擇選擇要遷移的小型檔案,而不是深入探索任何檔案。這個練習很實用,因為您可以藉此驗證即將進行的預定流程。如果可在這個檔案中運作,您的做法就是有效的;如果不是,您可以改回畫板。

此外,依檔案進行檔案 (以及一般的 Puppeteer 版本,因此所有變更不會使用相同的 npm 版本傳送),風險也隨之降低。我們挑選了 DeviceDescriptors.js 做為第一個檔案,因為這是程式碼集中最直接的檔案之一。完成這份準備工作並做出這麼小的改變,有點讓人眼花撩亂,但目標並非立即進行大規模的調整,而是要謹慎處理每個檔案。當您執行較複雜的檔案時,驗證方法所需的時間無庸置疑,能在遷移後省下大把時間。

請證明模式並重複執行

幸好,DeviceDescriptors.js 的變更已成功成功導入程式碼集,而計畫奏效了,我們期望結果會如期實現!如果您已經準備好了,隨時可以放鬆,正如我們所做的。使用 GitHub 標籤是將所有提取要求分組在一起的好方法,而我們發現在追蹤進度時相當實用。

進行遷移,日後再改善

至於個別 JavaScript 檔案,我們的程序如下:

  1. 將檔案從 .js 重新命名.ts
  2. 執行 TypeScript 編譯器。
  3. 修正所有問題。
  4. 建立提取要求

這類初始提取要求大多是擷取現有資料結構的 TypeScript 介面。以我們先前討論的 DeviceDescriptors.js 遷移第一個提取要求來說,程式碼取自:

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

後來:

interface Device {
  name: string,
  …
}

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

module.exports = devices;

在這個過程中,我們已逐一檢查程式碼集的每一行是否有問題。就像任何程式碼集已經過幾年,而且隨著時間而增加,對於程式碼集來說,還有機會重構程式碼並改善情況。特別是改用 TypeScript 時,我們發現有些地方需要稍微重新建構程式碼,就能加強使用編譯器,並提升型別安全性。

反觀者,一定要直接拒絕變更。遷移的目標是將程式碼集導入 TypeScript,而且在大規模遷移作業期間,您隨時都必須考量造成軟體和使用者故障的風險。盡量減少初步變更,將風險降到最低。檔案合併並遷移至 TypeScript 後,我們可以進行後續追蹤變更以改善程式碼,利用型別系統。請務必為遷移作業設定嚴格限制,並盡量避免超出範圍。

遷移測試以測試類型定義

將整個原始碼遷移至 TypeScript 後,我們就能專注於測試。我們的測試涵蓋範圍很廣,但都是以 JavaScript 編寫而成。這表示他們並未測試的是類型定義。專案的長期目標之一 (我們「還在努力開發」) 是利用 Puppeteer 直接提供高品質的類型定義,但在程式碼集中並未針對類型定義提供任何檢查結果。

將測試遷移至 TypeScript (按照相同程序、依檔案處理) 後,我們發現 TypeScript 有些問題,原本可能會讓使用者找到我們。現在,我們的測試不僅涵蓋所有功能,也可用於對 TypeScript 的品質檢查

身為負責 Puppeteer 程式碼集的工程師,TypeScript 已帶來莫大助益。搭配使用改良後的 CI 環境,不僅讓我們在處理 Puppeteer 時有更高的效率,也讓 TypeScript 能擷取原本可能提升到 npm 版本的錯誤。我們很高興提供高品質的 TypeScript 定義,讓使用 Puppeteer 的所有開發人員也能受惠於這項工作。

下載預覽頻道

建議您使用 Chrome Canary開發人員版Beta 版做為預設開發瀏覽器。這些預覽管道可讓您使用最新的開發人員工具、測試最先進的網路平台 API,以及在使用者操作之前在網站上找出問題!

與 Chrome 開發人員工具團隊聯絡

使用下列選項,在文章中討論新功能和異動,或與開發人員工具相關的任何其他內容。

  • 透過 crbug.com 提供建議或意見。
  • 如要回報開發人員工具問題,請在開發人員工具中依序點選「更多選項」更多   >「說明」 >「回報開發人員工具的問題」
  • @ChromeDevTools 張貼推文。
  • 歡迎前往開發人員工具的 YouTube 影片或開發人員工具的 YouTube 影片提供新功能留言。