โลกของการเขียนโปรแกรมกำลังเดือดด้วยการถกเถียงอย่างเข้มข้น หลังจาก Bill Hall ผู้สร้างภาษา Odin ได้เผยแพร่บทความที่ท้าทายมุมมองเรื่อง Package Managers are Evil การวิพากษ์วิจารณ์ของเขาได้จุดประกายการอภิปรายอย่างรุนแรงเกี่ยวกับเครื่องมือจัดการ dependency อัตโนมัติว่าช่วยเหลือหรือทำร้ายการพัฒนาซอฟต์แวร์
ข้อโต้แย้งหลักของ Hall ท้าทายสมมติฐานพื้นฐานในการเขียนโปรแกรมสมัยใหม่ เขาอ้างว่า package manager ทำให้สิ่งที่ผิดเป็นอัตโนมัติ - dependency hell - ทำให้นักพัฒนาสามารถสะสม dependency หลายพันตัวได้ง่ายขึ้นโดยไม่เข้าใจผลกระทบ การอภิปรายนี้เผยให้เห็นความแตกแยกลึกซึ้งในแนวทางที่นักพัฒนาใช้ในการนำโค้ดกลับมาใช้ใหม่และการจัดการโครงการ
ข้อโต้แย้งหลักที่ต่อต้าน Package Managers:
- ทำให้ dependency hell เป็นระบบอัตโนมัติแทนที่จะป้องกันไม่ให้เกิดขึ้น
- ซ่อนความซับซ้อนและต้นทุนที่แท้จริงของ dependencies
- ทำให้สามารถสะสม dependencies หลายพันตัวที่ไม่ได้รับการตรวจสอบ
- สร้างช่องโหว่ด้านความปลอดภัยผ่านการไว้วางใจแบบตาบอด
- นำไปสู่ภาระในการบำรุงรักษาและความรับผิดชอบต่อข้อบกพร่อง
ความขัดแย้งเรื่องระบบอัตโนมัติ
หัวใจของการถกเถียงอยู่ที่ว่าการจัดการ dependency ควรเป็นแบบอัตโนมัติหรือแบบแมนนวล Hall โต้แย้งว่า package manager ซ่อนความซับซ้อนและทำให้การเพิ่ม dependency ง่ายเกินไปโดยไม่ได้พิจารณาอย่างเหมาะสม เขาแนะนำว่าการจัดการ dependency แบบแมนนวลบังคับให้นักพัฒนาคิดอย่างรอบคอบเกี่ยวกับการเพิ่มแต่ละตัว ซึ่งอาจป้องกัน dependency tree ที่บวมได้
การตอบสนองจากชุมชนเผยให้เห็นประสบการณ์ที่หลากหลาย นักพัฒนาบางคนแบ่งปันเรื่องราวของโครงการ Rust ที่ดึง dependency ที่ไม่คาดคิดหลายสิบตัวจากการ import โดยตรงเพียงหนึ่งหรือสองตัว คนอื่นๆ ชี้ให้เห็นว่าการจัดการแบบแมนนวลไม่สามารถขยายขนาดได้สำหรับสภาพแวดล้อมองค์กรขนาดใหญ่ที่ผลิตภัณฑ์รวมส่วนประกอบหลายร้อยส่วนจากหลายทีมทั่วโลก
การอภิปรายนี้เน้นย้ำความตึงเครียดสำคัญระหว่างความสะดวกของนักพัฒนาและความสามารถในการบำรุงรักษาโครงการ แม้ว่าระบบอัตโนมัติจะประหยัดเวลา แต่นักวิจารณ์โต้แย้งว่าอาจนำไปสู่สถานการณ์ที่โครงการกลายเป็นพึ่งพาโค้ดที่นักพัฒนาไม่เคยตรวจสอบหรือเข้าใจ
เรื่องราวผลกระทบในโลกจริง
สมาชิกชุมชนหลายคนแบ่งปันตัวอย่างที่เป็นรูปธรรมของปัญหาที่เกี่ยวข้องกับ dependency นักพัฒนาคนหนึ่งอธิบายการค้นพบบั๊กมากมายใน SDL2 ซึ่งเป็นไลบรารีที่ใช้กันอย่างแพร่หลาย ทำให้ทีมของเขาพิจารณาเขียนระบบ windowing ของตัวเองตั้งแต่เริ่มต้น อีกคนหนึ่งเล่าถึงความยากลำบากในการทำซ้ำการสร้าง neural model ที่ถูกสร้างขึ้นโดยไม่มีการจัดการ dependency ที่เหมาะสม
ประสบการณ์แตกต่างกันอย่างมากตาม ecosystem ของภาษาโปรแกรม นักพัฒนา Go รายงานว่าต้องการ third-party package น้อยกว่าเนื่องจาก standard library ที่ครอบคลุมของภาษา ในขณะที่นักพัฒนา JavaScript อธิบายถึงความท้าทายในการจัดการ dependency tree ที่ซับซ้อนใน single-page application
การกำจัด npm และทำสิ่งต่างๆ แบบแมนนวลจะไม่ทำให้การสร้าง SPA มี dependency น้อยลง การสร้างจะช้าและเจ็บปวดอย่างเหลือเชื่อ
ความคิดเห็นนี้สะท้อนความกังวลทั่วไป - ว่าสภาพแวดล้อมการพัฒนาบางอย่างได้วิวัฒนาการมาจนพึ่งพา package ecosystem อย่างหนักจนการจัดการแบบแมนนวลกลายเป็นเรื่องที่ไม่สามารถทำได้
มิติของความไว้วางใจและความปลอดภัย
ส่วนสำคัญของการอภิปรายมุ่งเน้นไปที่ผลกระทบด้านความปลอดภัยของการจัดการ dependency อัตโนมัติ สมาชิกชุมชนถกเถียงว่านักพัฒนาไว้วางใจโค้ดสุ่มจากอินเทอร์เน็ตมากเกินไปหรือไม่ โดยบางคนโต้แย้งว่าโปรแกรมเมอร์จากสังคมที่มีความไว้วางใจสูงใช้ระดับความไว้วางใจที่ไม่เหมาะสมกับ repository โค้ดออนไลน์
การสนทนาเผยให้เห็นสิ่งที่บางคนเรียกว่า Gell-Mann amnesia effect ในการเขียนโปรแกรม - นักพัฒนาที่ไม่ไว้วางใจโค้ดของเพื่อนร่วมงานของตัวเองแต่กลับไว้วางใจ open-source package จากผู้เขียนที่ไม่รู้จักอย่างสุ่มสี่สุ่มห้า ความขัดแย้งนี้เน้นย้ำคำถามที่กว้างขึ้นเกี่ยวกับการประเมินคุณภาพโค้ดและการจัดการความเสี่ยงในการพัฒนาซอฟต์แวร์
ผู้เข้าร่วมหลายคนสังเกตว่าปัญหาความปลอดภัย แม้จะสำคัญ แต่ไม่ใช่ความกังวลเดียว ความรับผิดชอบต่อบั๊ก ภาระการบำรุงรักษา และความซับซ้อนของการรวมระบบสามารถเป็นปัญหาได้เท่าๆ กันสำหรับโครงการหลายๆ โครงการ
แนวทางทางเลือกและโซลูชัน
การถกเถียงได้สร้างข้อเสนอต่างๆ สำหรับโซลูชันแบบประนีประนอม บางคนแนะนำเครื่องมือที่ดีกว่าสำหรับการตรวจสอบ dependency รวมถึงบริการสแกนจากบุคคลที่สามที่รวมเข้ากับ package manager คนอื่นๆ สนับสนุนการจัดการ dependency แบบเลือกสรร โดยใช้ package manager เฉพาะกับไลบรารีที่มีขนาดใหญ่และได้รับการตรวจสอบแล้วเท่านั้น แทนที่จะเป็น micro-package
นักพัฒนาองค์กรอธิบายการใช้เครื่องมืออย่าง Nix สำหรับการจัดการ dependency ที่เชื่อถือได้มากขึ้น ในขณะที่คนอื่นๆ ชี้ไปที่แนวทางอย่าง vendoring dependency ด้วยเวอร์ชันที่ล็อค การอภิปรายเผยให้เห็นว่าบริบทการพัฒนาที่แตกต่างกัน - ตั้งแต่การพัฒนาเกมไปจนถึงระบบที่มีความปลอดภัยสำคัญ - มีความต้องการและข้อจำกัดที่แตกต่างกันอย่างมาก
การสนทนายังสัมผัสถึงบทบาทของ standard library ภาษาที่มีฟังก์ชันการทำงานในตัวที่ครอบคลุม เช่น Go ดูเหมือนจะสร้าง dependency sprawl น้อยกว่าเมื่อเทียบกับภาษาที่มี standard library น้อยที่ผลักดันฟังก์ชันการทำงานทั่วไปไปยัง external package
แนวทางทางเลือกที่ถูกหารือ:
- การจัดการ dependency แบบแมนนวลด้วย vendoring
- การใช้ภาษาโปรแกรมที่มี standard library ครอบคลุม (ตัวอย่าง Go )
- การจัดการ dependency แบบเลือกสรรเฉพาะแพ็กเกจที่สำคัญเท่านั้น
- บริการตรวจสอบจากบุคคลที่สามที่ผสานรวมเข้ากับ package manager
- เครื่องมืออย่าง Nix สำหรับการแก้ไข dependency ที่เชื่อถือได้มากขึ้น
- Git subtrees แทนการใช้ submodule สำหรับการจัดการ dependency
สรุป
การถกเถียงนี้สะท้อนความตึงเครียดที่กว้างขึ้นในการพัฒนาซอฟต์แวร์ระหว่างการพัฒนาอย่างรวดเร็วและความสามารถในการบำรุงรักษาระยะยาว แม้ว่า package manager จะเร่งการพัฒนาซอฟต์แวร์อย่างไม่ต้องสงสัยโดยทำให้การนำโค้ดกลับมาใช้ใหม่ง่ายขึ้น แต่พวกมันก็ได้แนะนำหมวดหมู่ปัญหาใหม่ที่อุตสาหกรรมยังคงเรียนรู้ที่จะจัดการ
การอภิปรายแนะนำว่าแทนที่จะมอง package manager ว่าดีหรือชั่วร้ายอย่างสากล นักพัฒนาอาจได้รับประโยชน์จากแนวทางที่มีความละเอียดอ่อนมากขึ้นที่พิจารณาบริบทโครงการ ความสามารถของทีม และความต้องการการบำรุงรักษาระยะยาว ขณะที่อุตสาหกรรมการเขียนโปรแกรมยังคงเติบโต การหาสมดุลที่เหมาะสมระหว่างระบบอัตโนมัติและการควบคุมแบบแมนนวลยังคงเป็นความท้าทายที่ต่อเนื่อง
อ้างอิง: Package Managers are Evil