Di chuyển Puppeteer sang TypeScript

Jack Franklin
Jack Franklin

Chúng tôi rất thích TypeScript trong nhóm Công cụ cho nhà phát triển — đến mức mã mới trong Công cụ cho nhà phát triển được tạo trong đó và chúng tôi đang thực hiện một quá trình di chuyển lớn toàn bộ cơ sở mã để được TypeScript kiểm tra kiểu. Bạn có thể tìm hiểu thêm về quá trình di chuyển này trong bài nói chuyện của chúng tôi tại Hội nghị Nhà phát triển Chrome năm 2020. Do đó, bạn cũng nên xem xét việc di chuyển cơ sở mã của Pupeteer sang TypeScript.

Lập kế hoạch di chuyển

Khi lên kế hoạch di chuyển, chúng tôi muốn có thể tiến hành từng bước nhỏ. Điều này giúp giảm chi phí di chuyển (bất cứ lúc nào bạn cũng chỉ làm việc trên một phần nhỏ của mã) và cũng giảm thiểu rủi ro. Nếu xảy ra sự cố với một trong các bước, bạn có thể dễ dàng hoàn nguyên sự cố đó. Puppeteer có rất nhiều người dùng và một bản phát hành bị lỗi sẽ gây ra vấn đề cho rất nhiều người dùng, vì vậy, điều quan trọng là chúng tôi phải giữ ở mức tối thiểu rủi ro gây lỗi.

Chúng tôi cũng rất may mắn khi Puppeteer đã triển khai một bộ kiểm thử đơn vị mạnh mẽ để đảm bảo mọi chức năng của công cụ này. Điều này có nghĩa là chúng ta có thể tự tin rằng chúng ta đã không làm hỏng mã khi di chuyển, nhưng cũng là do chúng ta không giới thiệu các thay đổi đối với API. Mục tiêu của việc di chuyển là hoàn thành việc di chuyển mà không có bất kỳ người dùng Puppeteer nào thậm chí còn nhận ra rằng chúng tôi đã di chuyển và kiểm thử là một phần quan trọng của chiến lược đó. Nếu không có phạm vi kiểm thử tốt, chúng tôi sẽ bổ sung dữ liệu đó trước khi tiếp tục di chuyển.

Việc thực hiện bất kỳ thay đổi mã nào mà không cần kiểm thử sẽ rất rủi ro, nhưng những thay đổi ở nơi bạn chạm vào toàn bộ tệp hoặc toàn bộ cơ sở mã sẽ đặc biệt rủi ro. Khi thực hiện các thay đổi cơ học, rất dễ để bỏ lỡ một bước và trong nhiều trường hợp các bài kiểm thử đã phát hiện một vấn đề bỏ qua cả người triển khai và người đánh giá.

Một điều mà chúng tôi đã đầu tư thời gian ngay từ đầu là thiết lập tính năng Tích hợp liên tục (CI). Chúng tôi nhận thấy CI chạy dựa trên các yêu cầu lấy dữ liệu không ổn định và thường không thành công. Việc này xảy ra thường xuyên đến mức chúng tôi trở thành thói quen bỏ qua CI và vẫn hợp nhất các yêu cầu lấy dữ liệu, giả sử rằng thất bại là vấn đề một lần đối với CI thay vì vấn đề trong Puppeteer.

Sau một đợt bảo trì chung và dành thời gian để khắc phục một số yếu tố không ổn định trong quá trình kiểm thử thông thường, chúng tôi đã chuyển sang trạng thái đạt một cách nhất quán hơn nhiều, cho phép chúng tôi nghe CI và biết được rằng một lỗi xảy ra cho thấy thực sự đang có vấn đề. Công việc này không hấp dẫn và thật khó chịu khi phải chứng kiến các lần chạy CI liên tục, nhưng điều quan trọng là bộ thử nghiệm của chúng tôi chạy một cách đáng tin cậy khi xét đến số lượng yêu cầu kéo mà quá trình di chuyển đang gửi vào đó.

Chọn và chuyển một tệp

Tại thời điểm này, chúng tôi đã sẵn sàng di chuyển và sử dụng máy chủ CI mạnh mẽ với đầy đủ các thử nghiệm để theo dõi. Thay vì tìm hiểu sâu về mọi tệp tuỳ ý, chúng tôi chủ động chọn một tệp nhỏ để di chuyển. Đây là một bài tập hữu ích vì nó cho phép bạn xác thực quy trình theo kế hoạch mà bạn sắp thực hiện. Nếu cách của bạn hoạt động trên tệp này thì tức là phương pháp của bạn hợp lệ; nếu không, bạn có thể quay lại bảng vẽ.

Ngoài ra, việc xử lý từng tệp (và với các bản phát hành Puppeteer thông thường, vì vậy, mọi thay đổi đều không được gửi trong cùng một phiên bản npm) giúp giảm rủi ro. Chúng tôi đã chọn DeviceDescriptors.js làm tệp đầu tiên vì đây là một trong những tệp đơn giản nhất trong cơ sở mã. Bạn có thể cảm thấy hơi choáng ngợp khi thực hiện tất cả công việc chuẩn bị này và thực hiện một thay đổi nhỏ như vậy, nhưng mục tiêu không phải là thực hiện thay đổi lớn ngay lập tức mà phải tiến hành một cách thận trọng và có phương pháp theo từng tệp. Thời gian dành cho việc xác thực phương pháp này chắc chắn sẽ giúp tiết kiệm thời gian sau này trong quá trình di chuyển khi bạn gặp những tệp phức tạp hơn.

Chứng minh mẫu và lặp lại

Rất may là thay đổi đối với DeviceDescriptors.js đã đưa được vào cơ sở mã và kế hoạch đã hoạt động như chúng tôi mong đợi! Đến lúc này, bạn đã sẵn sàng bắt tay vào làm và tiếp tục, đó chính xác là những gì chúng tôi đã làm. Sử dụng nhãn GitHub là một cách thực sự hiệu quả để nhóm tất cả các yêu cầu lấy dữ liệu lại với nhau. Chúng tôi nhận thấy điều này rất hữu ích trong việc theo dõi tiến trình.

Di chuyển và cải thiện ngôn ngữ này sau

Đối với bất kỳ tệp JavaScript riêng lẻ nào, quy trình của chúng tôi là:

  1. Đổi tên tệp từ .js thành .ts.
  2. Chạy trình biên dịch TypeScript.
  3. Khắc phục mọi vấn đề.
  4. Tạo yêu cầu kéo.

Hầu hết công việc trong các yêu cầu lấy dữ liệu ban đầu này là trích xuất giao diện TypeScript cho các cấu trúc dữ liệu hiện có. Trong trường hợp yêu cầu lấy dữ liệu đầu tiên đã di chuyển DeviceDescriptors.js mà chúng ta đã thảo luận trước đó, mã sẽ bắt nguồn từ:

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

Và trở thành:

interface Device {
  name: string,
  …
}

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

module.exports = devices;

Theo đó, chúng tôi đã xử lý từng dòng trong cơ sở mã để tìm vấn đề. Giống như với những cơ sở mã đã tồn tại vài năm và phát triển theo thời gian, bạn có thể có cơ hội tái cấu trúc mã và cải thiện tình hình. Đặc biệt là khi chuyển sang TypeScript, chúng tôi nhận thấy có những vị trí mà việc tái cấu trúc mã một chút sẽ cho phép chúng tôi dựa vào trình biên dịch nhiều hơn và có được độ an toàn về loại tốt hơn.

Ngược lại, theo quan sát, bạn nên tránh thực hiện những thay đổi này ngay lập tức. Mục tiêu của việc di chuyển này là đưa cơ sở mã vào TypeScript. Và trong mọi trường hợp di chuyển lớn, bạn đều phải suy nghĩ về nguy cơ gây ra sự cố cho phần mềm và cho người dùng của bạn. Bằng cách giảm thiểu những thay đổi ban đầu, chúng tôi đã hạn chế rủi ro ở mức thấp. Sau khi tệp được hợp nhất và di chuyển sang TypeScript, chúng ta có thể thực hiện các thay đổi tiếp theo nhằm cải thiện mã nhằm tận dụng hệ thống kiểu. Hãy nhớ thiết lập các giới hạn nghiêm ngặt cho quá trình di chuyển và cố gắng tuân thủ các giới hạn đó.

Di chuyển các bài kiểm thử để kiểm thử định nghĩa kiểu

Sau khi di chuyển toàn bộ mã nguồn sang TypeScript, chúng ta có thể chuyển trọng tâm vào chương trình kiểm thử. Các bài kiểm thử của chúng tôi có phạm vi bao phủ rộng, nhưng tất cả đều được viết bằng JavaScript. Điều này có nghĩa là một tính năng mà họ không kiểm thử là định nghĩa kiểu. Một trong những mục tiêu dài hạn của dự án (chúng tôi vẫn đang thực hiện) là cung cấp các định nghĩa kiểu chất lượng cao ngay từ đầu bằng Puppeteer, nhưng chúng tôi không có bất kỳ bước kiểm tra nào trong cơ sở mã của mình về định nghĩa kiểu.

Bằng cách di chuyển các bài kiểm thử sang TypeScript (theo cùng một quy trình, xử lý từng tệp), chúng tôi đã phát hiện thấy các vấn đề với TypeScript mà lẽ ra người dùng có thể tự tìm thấy cho chúng tôi. Giờ đây, các bài kiểm thử của chúng tôi không chỉ kiểm tra toàn bộ chức năng, mà còn đóng vai trò kiểm tra chất lượng của TypeScript!

Chúng tôi đã hưởng lợi rất nhiều từ TypeScript với tư cách là các kỹ sư làm việc trên cơ sở mã Puppeteer. Cùng với môi trường CI được cải thiện rất nhiều, công nghệ này cho phép chúng tôi làm việc hiệu quả hơn khi làm việc trên Puppeteer và giúp TypeScript phát hiện các lỗi mà lẽ ra đã được chuyển thành bản phát hành npm. Chúng tôi rất vui khi được chuyển các định nghĩa TypeScript chất lượng cao để tất cả nhà phát triển sử dụng Puppeteer cũng có thể hưởng lợi từ công việc này.

Tải các kênh xem trước xuống

Hãy cân nhắc sử dụng Chrome Canary, Dev hoặc Beta làm trình duyệt phát triển mặc định. Những kênh xem trước này cung cấp cho bạn quyền truy cập vào các tính năng mới nhất của Công cụ cho nhà phát triển, kiểm thử API nền tảng web tiên tiến và tìm ra các sự cố trên trang web của bạn trước khi người dùng làm việc đó!

Liên hệ với nhóm Công cụ của Chrome cho nhà phát triển

Hãy sử dụng các lựa chọn sau để thảo luận về các tính năng mới và thay đổi trong bài đăng hoặc bất kỳ vấn đề nào khác liên quan đến Công cụ cho nhà phát triển.

  • Gửi đề xuất hoặc phản hồi cho chúng tôi qua crbug.com.
  • Báo cáo sự cố Công cụ cho nhà phát triển bằng cách sử dụng mục Tuỳ chọn khác   Thêm   > Trợ giúp > Báo cáo sự cố Công cụ cho nhà phát triển trong Công cụ cho nhà phát triển.
  • Tweet tại @ChromeDevTools.
  • Để lại nhận xét về Video trên YouTube của chúng tôi về Tính năng mới trong Video trên YouTube của Công cụ cho nhà phát triển hoặc mẹo Công cụ cho nhà phát triển.