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

แจ็ค แฟรงคลิน
แจ็ค แฟรงคลิน

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

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

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

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

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

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

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

เลือกและนำไฟล์มา 1 ไฟล์

ณ จุดนี้ เราพร้อมที่จะย้ายข้อมูลและเซิร์ฟเวอร์ 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;

ซึ่งหมายความว่าเราดำเนินการตรวจสอบโค้ดเบสทุกบรรทัดเพื่อหาปัญหา ฐานของโค้ดใดๆ ที่มีมา 2-3 ปีและเติบโตขึ้นเมื่อเวลาผ่านไป ก็ยังมีโอกาสในการปรับโครงสร้างโค้ดและปรับปรุงสถานการณ์ได้ โดยเฉพาะอย่างยิ่งเมื่อเปลี่ยนไปใช้ TypeScript เราเห็นตำแหน่งที่มีการปรับโครงสร้างโค้ดเล็กน้อย ช่วยให้เราสามารถพึ่งพาคอมไพเลอร์มากขึ้นและได้รับความปลอดภัยของประเภทที่ดีขึ้น

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

การย้ายการทดสอบเพื่อทดสอบคำจำกัดความของประเภท

เมื่อย้ายข้อมูลซอร์สโค้ดทั้งหมดไปยัง TypeScript แล้ว เราจะมุ่งเน้นการทดสอบได้ การทดสอบของเรามีความครอบคลุมที่กว้างมาก แต่ทั้งหมดเขียนด้วย JavaScript ซึ่งหมายความว่าสิ่งหนึ่งที่พวกเขาไม่ได้ทดสอบคือคำจำกัดความประเภทของเรา หนึ่งในเป้าหมายระยะยาวของโครงการนี้ (ซึ่งเรากำลังกำลังดำเนินการอยู่) คือการส่งคำจำกัดความประเภทที่มีคุณภาพสูงให้ทันทีด้วย Puppeteer แต่เรายังไม่มีการตรวจสอบในฐานของโค้ดเกี่ยวกับคำจำกัดความประเภทของเรา

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

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

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

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

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

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

  • ส่งคำแนะนำหรือความคิดเห็นถึงเราผ่าน crbug.com
  • รายงานปัญหาเกี่ยวกับเครื่องมือสำหรับนักพัฒนาเว็บโดยใช้ตัวเลือกเพิ่มเติม   เพิ่มเติม   > ความช่วยเหลือ > รายงานปัญหาเกี่ยวกับเครื่องมือสำหรับนักพัฒนาเว็บในเครื่องมือสำหรับนักพัฒนาเว็บ
  • ทวีตที่ @ChromeDevTools
  • โปรดแสดงความคิดเห็นในวิดีโอ YouTube เกี่ยวกับมีอะไรใหม่ในเครื่องมือสำหรับนักพัฒนาเว็บในวิดีโอ YouTube หรือเคล็ดลับสำหรับเครื่องมือสำหรับนักพัฒนาเว็บ