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

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

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

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

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

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

สิ่งหนึ่งที่เราใช้เวลาล่วงหน้าในการดำเนินการคือการตั้งค่า Continuous Integration (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;

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

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

การย้ายข้อมูลการทดสอบเพื่อทดสอบการกําหนดประเภท

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

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

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

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

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

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

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