กรณีศึกษา: การแก้ไขข้อบกพร่องของ Angular ที่ดียิ่งขึ้นด้วยเครื่องมือสำหรับนักพัฒนาเว็บ

ประสบการณ์การแก้ไขข้อบกพร่องที่ดีขึ้น

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

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

รหัสการละเว้นข้อมูล

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

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

ในทางปฏิบัติ เครื่องมือสำหรับนักพัฒนาเว็บของ Chrome สามารถซ่อนโค้ดที่ระบุไว้ดังกล่าวโดยอัตโนมัติในสแต็กเทรซ ต้นไม้แหล่งที่มา กล่องโต้ตอบเปิดด่วน และปรับปรุงลักษณะการแยกขั้นตอนและการดําเนินการต่อในโปรแกรมแก้ไขข้อบกพร่อง

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

ส่วนขยายการแมปแหล่งที่มา x_google_ignoreList

ในแผนที่แหล่งที่มา ช่อง x_google_ignoreList ใหม่จะอ้างอิงอาร์เรย์ sources และแสดงดัชนีของแหล่งที่มาของบุคคลที่สามทั้งหมดที่รู้จักในแผนที่แหล่งที่มานั้น เมื่อแยกวิเคราะห์แผนที่ซอร์สโค้ด เครื่องมือสำหรับนักพัฒนาเว็บใน Chrome จะใช้ข้อมูลนี้เพื่อพิจารณาว่าควรเพิ่มส่วนใดของโค้ดลงในรายการที่ควรละเว้น

ด้านล่างนี้คือสําเนาที่มาของไฟล์ out.js ที่สร้างขึ้น sources เดิม 2 รายการที่มีส่วนร่วมในการสร้างไฟล์เอาต์พุต ได้แก่ foo.js และ lib.js รายการแรกคือสิ่งที่นักพัฒนาเว็บไซต์เขียนขึ้น ส่วนรายการที่ 2 คือเฟรมเวิร์กที่ใช้

{
  "version" : 3,
  "file": "out.js",
  "sourceRoot": "",
  "sources": ["foo.js", "lib.js"],
  "sourcesContent": ["...", "..."],
  "names": ["src", "maps", "are", "fun"],
  "mappings": "A,AAAB;;ABCDE;"
}

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

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

ขณะนี้มีข้อมูลเพิ่มเติมอีก 1 รายการที่รวมไว้ในแผนที่แหล่งที่มาเพื่อระบุว่าแหล่งที่มาใดเป็นโค้ดของบุคคลที่สามหรือโค้ดแรก

{
  ...
  "sources": ["foo.js", "lib.js"],
  "x_google_ignoreList": [1],
  ...
}

ฟิลด์ x_google_ignoreList ใหม่มีดัชนีเดียวที่อ้างอิงอาร์เรย์ sources: 1 ซึ่งระบุว่าภูมิภาคที่แมปกับ lib.js คือโค้ดของบุคคลที่สามที่ควรเพิ่มลงในรายการละเว้นโดยอัตโนมัติ

ในตัวอย่างที่ซับซ้อนมากขึ้นซึ่งแสดงด้านล่าง ดัชนี 2, 4 และ 5 จะระบุว่าภูมิภาคที่แมปกับ lib1.ts, lib2.coffee และ hmr.js เป็นโค้ดของบุคคลที่สามทั้งหมดที่ควรเพิ่มลงในรายการละเว้นโดยอัตโนมัติ

{
  ...
  "sources": ["foo.html", "bar.css", "lib1.ts", "baz.js", "lib2.coffee", "hmr.js"],
  "x_google_ignoreList": [2, 4, 5],
  ...
}

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

x_google_ignoreList ใน Angular

ตั้งแต่ Angular v14.1.0 เนื้อหาของโฟลเดอร์ node_modules และ webpack ได้รับการทําเครื่องหมายเป็น"to ignore"

ซึ่งทำได้ผ่านการเปลี่ยนแปลงใน angular-cli โดยสร้างปลั๊กอินที่เชื่อมต่อกับCompilerโมดูลของ webpack

ปลั๊กอิน webpack ที่วิศวกรของเราสร้างจะฮุกเข้ากับระยะ PROCESS_ASSETS_STAGE_DEV_TOOLING และป้อนข้อมูลในช่อง x_google_ignoreList ในแผนที่ซอร์สโค้ดสําหรับชิ้นงานขั้นสุดท้ายที่ webpack สร้างขึ้นและเบราว์เซอร์โหลด

const map = JSON.parse(mapContent) as SourceMap;
const ignoreList = [];

for (const [index, path] of map.sources.entries()) {
  if (path.includes('/node_modules/') || path.startsWith('webpack/')) {
    ignoreList.push(index);
  }
}

map[`x_google_ignoreList`] = ignoreList;
compilation.updateAsset(name, new RawSource(JSON.stringify(map)));

สแต็กเทรซที่ลิงก์

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

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

ในการแก้ปัญหานี้ DevTools จึงแสดงกลไกที่เรียกว่า "Async Stack Tagging API" ในออบเจ็กต์ console ซึ่งช่วยให้นักพัฒนาเฟรมเวิร์กสามารถบอกทั้งตำแหน่งที่ตั้งกำหนดเวลาการดำเนินการและตำแหน่งที่ดำเนินการเหล่านี้

Async Stack Tagging API

หากไม่มีการติดแท็กสแต็กแบบแอซิงโครนัส สแต็กเทรซสําหรับโค้ดที่เฟรมเวิร์กเรียกใช้แบบแอซิงโครนัสด้วยวิธีที่ซับซ้อนจะปรากฏขึ้นโดยไม่มีการเชื่อมต่อกับโค้ดที่ตั้งเวลาไว้