การย้ายข้อมูล Puppeteer ไปยัง TypeScript

ทีมเครื่องมือสำหรับนักพัฒนาเว็บชื่นชอบ TypeScript มากจนโค้ดใหม่ในเครื่องมือสำหรับนักพัฒนาเว็บเขียนขึ้นใน TypeScript และเรากำลังอยู่ระหว่างการย้ายข้อมูลฐานของโค้ดทั้งหมดครั้งใหญ่เพื่อให้ TypeScript ตรวจสอบประเภทได้ ดูข้อมูลเพิ่มเติมเกี่ยวกับการย้ายข้อมูลดังกล่าวได้ในการพูดคุยของเราที่ Chrome Dev Summit 2020 ดังนั้นจึงเป็นเรื่องสมเหตุสมผลที่จะพิจารณาย้ายข้อมูลฐานโค้ดของ Puppeteer ไปยัง TypeScript ด้วย

วางแผนการย้ายข้อมูล

เมื่อวางแผนวิธีย้ายข้อมูล เราต้องการก้าวหน้าไปทีละเล็กทีละน้อย ซึ่งจะช่วยลดค่าใช้จ่ายในการย้ายข้อมูล (คุณจะทำงานกับโค้ดเพียงส่วนเล็กๆ ในแต่ละครั้ง) และลดความเสี่ยงด้วย หากเกิดข้อผิดพลาดในขั้นตอนใดขั้นตอนหนึ่ง คุณก็สามารถเปลี่ยนกลับได้อย่างง่ายดาย Puppeteer มีผู้ใช้จำนวนมาก และเวอร์ชันที่ใช้งานไม่ได้จะทำให้เกิดปัญหาสำหรับผู้ใช้จำนวนมาก ดังนั้นเราจึงต้องลดความเสี่ยงของการเปลี่ยนแปลงที่ส่งผลกับส่วนอื่นในระบบให้เหลือน้อยที่สุด

นอกจากนี้ เรายังโชคดีที่ Puppeteer มีชุดการทำ Unit Test ที่มีประสิทธิภาพซึ่งครอบคลุมฟังก์ชันการทำงานทั้งหมด ซึ่งหมายความว่าเรามั่นใจได้ว่าเราจะไม่ทำลายโค้ดขณะย้ายข้อมูล และจะไม่ทำการเปลี่ยนแปลง API ของเราด้วย เป้าหมายของการย้ายข้อมูลคือการดำเนินการให้เสร็จสมบูรณ์โดยที่ผู้ใช้ Puppeteer ไม่รู้ด้วยซ้ำว่าเราได้ย้ายข้อมูลแล้ว และการทดสอบก็เป็นส่วนสำคัญของกลยุทธ์ดังกล่าว หากเราไม่มีความครอบคลุมของการทดสอบที่ดี เราจะเพิ่มความครอบคลุมดังกล่าวก่อนที่จะดำเนินการย้ายข้อมูลต่อ

การเปลี่ยนแปลงโค้ดโดยไม่มีการทดสอบมีความเสี่ยง แต่การเปลี่ยนแปลงที่ส่งผลต่อทั้งไฟล์หรือฐานของโค้ดทั้งหมดมีความเสี่ยงสูงเป็นพิเศษ เมื่อทำการเปลี่ยนแปลงทางกลไก คุณอาจพลาดขั้นตอนใดขั้นตอนหนึ่งได้ง่ายๆ และในการทดสอบหลายครั้ง เราพบปัญหาที่ทั้งผู้ติดตั้งใช้งานและผู้ตรวจสอบมองข้ามไป

สิ่งหนึ่งที่เราใช้เวลาลงทุนตั้งแต่แรกคือการตั้งค่าการรวมอย่างต่อเนื่อง (CI) เราสังเกตเห็นว่าการเรียกใช้ CI กับ Pull Request ไม่เสถียรและมักจะล้มเหลว เหตุการณ์นี้เกิดขึ้นบ่อยมากจนเราติดนิสัยไม่สนใจ CI และผสาน Pull Request ไปเลย โดยคิดว่าความล้มเหลวเป็นปัญหาที่เกิดขึ้นครั้งเดียวใน CI มากกว่าที่จะเป็นปัญหาใน Puppeteer

หลังจากทำการบำรุงรักษาทั่วไปและใช้เวลาในการแก้ไขการทดสอบที่ล้มเหลวเป็นประจำ เราก็ทำให้การทดสอบผ่านได้อย่างสม่ำเสมอมากขึ้น ซึ่งช่วยให้เราสามารถรับฟัง CI และทราบว่าความล้มเหลวบ่งบอกถึงปัญหาจริง งานนี้ไม่ได้ดูน่าตื่นเต้นและน่าหงุดหงิดที่ต้องดูการเรียกใช้ CI อย่างไม่สิ้นสุด แต่การมีชุดโปรแกรมทดสอบที่ทำงานได้อย่างน่าเชื่อถือเป็นสิ่งสำคัญ เนื่องจากจำนวน Pull Request ที่การย้ายข้อมูลส่งมา

เลือกและวางไฟล์ 1 ไฟล์

ตอนนี้เราพร้อมที่จะย้ายข้อมูลแล้ว และมีเซิร์ฟเวอร์ CI ที่มีประสิทธิภาพซึ่งเต็มไปด้วยการทดสอบเพื่อคอยช่วยเหลือเรา เราเลือกไฟล์ขนาดเล็กเพื่อย้ายข้อมูลโดยเฉพาะแทนที่จะเลือกไฟล์ใดก็ได้ การดำเนินการนี้มีประโยชน์เนื่องจากช่วยให้คุณตรวจสอบกระบวนการที่วางแผนไว้ซึ่งกำลังจะดำเนินการได้ หากใช้ได้กับไฟล์นี้ แสดงว่าแนวทางของคุณใช้ได้ แต่หากใช้ไม่ได้ คุณก็กลับไปเริ่มต้นใหม่ได้

นอกจากนี้ การตรวจสอบไฟล์ทีละไฟล์ (และมีการเผยแพร่ Puppeteer เป็นประจำเพื่อให้การเปลี่ยนแปลงทั้งหมดไม่ได้อยู่ใน npm เวอร์ชันเดียวกัน) ยังช่วยลดความเสี่ยงได้อีกด้วย เราเลือก DeviceDescriptors.js เป็นไฟล์แรก เนื่องจากเป็นไฟล์ที่ตรงไปตรงมาที่สุดในโค้ดเบส การเตรียมการทั้งหมดนี้อาจดูเหมือนเป็นการเปลี่ยนแปลงเล็กน้อย แต่เป้าหมายของเราไม่ใช่การเปลี่ยนแปลงครั้งใหญ่ในทันที แต่เป็นการดำเนินการอย่างระมัดระวังและเป็นระบบทีละไฟล์ เวลาที่ใช้ในการตรวจสอบแนวทางจะช่วยประหยัดเวลาในภายหลังเมื่อย้ายข้อมูลไฟล์ที่ซับซ้อนมากขึ้น

พิสูจน์รูปแบบและทำซ้ำ

โชคดีที่การเปลี่ยนแปลงDeviceDescriptors.jsเข้าสู่ฐานของโค้ดได้สำเร็จ และแผนก็ทำงานได้ตามที่เราหวังไว้ ถึงตอนนี้คุณก็พร้อมที่จะลงมือทำอย่างจริงจังแล้ว ซึ่งเป็นสิ่งที่เราทำ การใช้ป้ายกำกับ GitHub เป็นวิธีที่ดีในการจัดกลุ่มคำขอ Pull Request ทั้งหมดไว้ด้วยกัน และเราพบว่าวิธีนี้มีประโยชน์ในการติดตามความคืบหน้า

ย้ายข้อมูลและปรับปรุงในภายหลัง

สำหรับไฟล์ JavaScript แต่ละไฟล์ กระบวนการของเรามีดังนี้

  1. เปลี่ยนชื่อไฟล์จาก .js เป็น .ts
  2. เรียกใช้คอมไพเลอร์ TypeScript
  3. แก้ไขปัญหา
  4. สร้างPull Request

งานส่วนใหญ่ใน Pull Request เริ่มต้นเหล่านี้คือการแยกอินเทอร์เฟซ TypeScript สำหรับโครงสร้างข้อมูลที่มีอยู่ ในกรณีของ Pull Request แรกที่ย้ายข้อมูล 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 ด้วย

เราได้รับประโยชน์อย่างมากจาก TypeScript ในฐานะวิศวกรที่ทำงานในฐานของโค้ด Puppeteer เมื่อรวมกับสภาพแวดล้อม CI ที่ได้รับการปรับปรุงอย่างมากแล้ว ก็ช่วยให้เราทำงานกับ Puppeteer ได้อย่างมีประสิทธิภาพมากขึ้น และ TypeScript ยังช่วยตรวจจับข้อบกพร่องที่อาจหลุดไปในการเผยแพร่ npm ได้อีกด้วย เรายินดีเป็นอย่างยิ่งที่จะได้เผยแพร่คำจำกัดความของ TypeScript คุณภาพสูงเพื่อให้ผู้พัฒนาทุกคนที่ใช้ Puppeteer ได้รับประโยชน์จากงานนี้ด้วย

ดาวน์โหลดช่องตัวอย่าง

ลองใช้ Chrome Canary, Dev หรือ Beta เป็นเบราว์เซอร์เริ่มต้นสำหรับการพัฒนา ช่องตัวอย่างเหล่านี้ช่วยให้คุณเข้าถึงฟีเจอร์ล่าสุดของ DevTools, ทดสอบ API ของแพลตฟอร์มเว็บที่ล้ำสมัย และช่วยคุณค้นหาปัญหาในเว็บไซต์ก่อนที่ผู้ใช้จะพบ

ติดต่อทีมเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome

ใช้ตัวเลือกต่อไปนี้เพื่อพูดคุยเกี่ยวกับฟีเจอร์ใหม่ การอัปเดต หรือสิ่งอื่นๆ ที่เกี่ยวข้องกับเครื่องมือสำหรับนักพัฒนาเว็บ