- กรณี left-pad เป็นตัวอย่างสำคัญที่แสดงให้เห็นถึง ความขัดแย้งของกฎและคุณค่า ระหว่างชุมชนโอเพนซอร์ส, NPM และภาคธุรกิจ
- การตัดสินใจลบแพ็กเกจนี้ไม่ได้เกิดจาก ตรรกะ ความโกรธ หรือความโลภ แต่เป็นการกระทำที่มาจากความจริงใจและหลักการภายในของตนเอง
- ในสถานการณ์ที่ NPM ละเมิดกฎของตัวเอง ด้วยการยอมอ่อนข้อให้กับข้อเรียกร้องของ Kik Messenger ผู้เขียนจึงเลือกที่จะลบแพ็กเกจทั้งหมดของตน
- หลังเหตุการณ์ดังกล่าว ความหลงใหลต่อโอเพนซอร์สได้เปลี่ยนไป และความสนใจก็ย้ายไปสู่สาขาใหม่อย่างธุรกิจ การตลาด และการบริหารทีม
- กรณี left-pad กลายเป็นจุดเริ่มต้นให้ทั้งนักพัฒนาและวงการสตาร์ตอัป กลับมาทบทวนแก่นแท้ของโอเพนซอร์สและความซับซ้อนของการตัดสินใจ
เบื้องหลังของเหตุการณ์และการตัดสินใจ
- เมื่อเวลาผ่านไป 8 ปีนับจากเหตุการณ์ left-pad ผู้เขียนได้แบ่งปันประสบการณ์และความคิดส่วนตัว
- ในช่วงเวลานั้น ผู้เขียนใช้เวลาส่วนใหญ่อยู่ ท่ามกลางธรรมชาติที่ไม่มีสัญญาณติดต่อถึง เพื่อทบทวนตนเอง และการตัดสินใจลบแพ็กเกจก็เกิดขึ้นในกระบวนการนี้
- การตัดสินใจนี้ไม่ได้มาจาก การตัดสินเชิงตรรกะ ความโกรธ หรือความโลภ แต่เริ่มต้นจากหลักการภายในของตนเองว่า "ถ้า NPM ละเมิดกฎของตัวเอง แพ็กเกจทั้งหมดของฉันก็ควรถูกลบเช่นกัน"
- ไม่ได้เป็น "คนยึดกฎแบบเคร่งครัด" เสียทีเดียว แต่เป็น ท่าทีที่ให้ความสำคัญกับจิตวิญญาณของกฎมากกว่า
- ในสถานการณ์ที่บริษัทอย่าง Kik Messenger ใช้ การข่มขู่และอำนาจต่อชุมชนโอเพนซอร์ส NPM กลับเพิกเฉยต่อกฎที่ตนตั้งไว้เองและให้ความสำคัญกับผลประโยชน์ของบริษัทเป็นอันดับแรก
โครงสร้างความขัดแย้งระหว่าง NPM กับชุมชน
- ผู้เขียนไม่ได้กลัวการข่มขู่ของ Kik แต่ NPM กลับกลัวการสูญเสีย Kik
- การตีความเหตุการณ์นี้อย่างง่าย ๆ ว่าเป็นเพียง "ชายที่โกรธแล้วลุกขึ้นต่อต้านบริษัทยักษ์ใหญ่" เป็นมุมมองที่ลดทอนความซับซ้อน โดยมองข้าม บริบทของเหตุการณ์ ลำดับเวลา และน้ำหนักของการตัดสินใจ
- ฝั่ง NPM ไม่ได้เผชิญกับเหตุการณ์ที่ฉับพลันหรือคาดไม่ถึง แต่โดยรวมกลับมี ท่าทีวางอำนาจใส่นักพัฒนา และผลักภาระความรับผิดชอบทั้งหมดมาให้ผู้เขียนผ่านการตัดสินใจหลายอย่างที่ไม่สอดคล้องกัน
โครงสร้างของแพ็กเกจและผลกระทบ
- งานโอเพนซอร์สของผู้เขียนส่วนใหญ่ถูกแยกออกเป็นบทบาทเล็ก ๆ ตามปรัชญาแบบ Unix จนประกอบด้วยแพ็กเกจกว่า 350 รายการ
- แม้ดูเผิน ๆ จะเหมือนแทบไม่มีร่องรอยการใช้งาน แต่เนื่องจาก NPM ไม่เปิดเผยสถิติการใช้งาน จึงเป็นสถานการณ์ที่ไม่อาจประเมินขอบเขตของผลกระทบได้
- ผู้ใช้ไม่มีทางรู้ผลกระทบที่แท้จริงจากการลบแพ็กเกจ และ NPM เองก็ไม่ได้พยายามตรวจสอบระดับผลกระทบหรือ ป้องกันปัญหาจากการลบอย่างไร้การควบคุม
การเปลี่ยนแปลงและการเติบโตหลังผ่านไป 8 ปี
- ไม่กี่เดือนหลังเหตุการณ์ left-pad ผู้เขียนลาออกจากงานหลักและออกจากสหรัฐอเมริกา เพื่อออกตามหาเส้นทางของตนเองในสภาพแวดล้อมใหม่ ๆ เช่น โมร็อกโก จอร์แดน ตุรกี และอินโดนีเซีย
- ผู้เขียนได้สัมผัสทั้ง ช่วงเวลาราวกับความตายที่ความหลงใหลต่อโอเพนซอร์สขาดสะบั้นลง และช่วงเวลาที่ได้เกิดใหม่อีกครั้งพร้อมความสนใจใหม่ ๆ
- ปัจจุบันผู้เขียนทุ่มเทให้กับ ธุรกิจ การตลาด การบริหารบริษัทและทีม รวมถึงสาขาอื่น ๆ ที่หลากหลาย ด้วยความหลงใหลไม่ต่างจากการเขียนโปรแกรม
- ผู้เขียนส่งต่อข้อความว่าชีวิตยังคงดำเนินต่อไป และกรณี left-pad ก็ยังคงเป็นจุดให้ย้อนทบทวนถึง การตัดสินใจอย่างเสรี คุณค่าของชุมชน และความซับซ้อนของกระบวนการตัดสินใจ
2 ความคิดเห็น
แม้จะเป็นเหตุการณ์ที่มีผลกระทบมาก แต่ถึงไม่ต้องอ่านบทความของผู้เขียนแพ็กเกจก็ยังคิดได้ว่าความผิดไม่ได้อยู่ที่เขาเป็นหลัก แต่อยู่ที่บริษัทและระบบที่พัวพันกันมากกว่า
ความคิดเห็นจาก Hacker News
พูดตามตรงคือรู้สึกว่าอ่านบล็อกโพสต์นี้แล้วครึ่งหนึ่งก็ยังไม่ค่อยเข้าใจ เหมือนพลาดบริบทบางอย่างไป แต่ก็ชอบที่ "left pad guy" เป็นคนมาสรุปเหตุการณ์เอง
แต่ข้ออ้างต่อไปนี้ให้ความรู้สึกแปลก ๆ อยู่เหมือนกัน
หลังเหตุการณ์ left-pad ก็เข้าใจชัดเจนเลยว่าทำไม
เป็นเรื่องเล็กน้อย แต่
libc ที่ผมใช้บนโทรศัพท์ตอนนี้มีขนาด 1MiB ซึ่งใหญ่กว่า Unix แบบดั้งเดิมถึง 16 เท่า
สรุปได้ว่าอย่างน้อย 90% ของ libc ขัดกับปรัชญา Unix
ถ้าไปอ่าน Lions Book หรือ APUE แล้วตามด้วยคู่มือ pthreads หรือสเปก ANSI C ของ
setlocale()จะเห็นเลยว่าเป็นคนละปรัชญากันถ้ามองว่าสองอย่างนี้คือสิ่งเดียวกัน ก็เป็นหลักฐานว่าคุณไม่ได้รู้สึกร่วมอย่างจริงจังกับปรัชญาใดเลย
เพราะความหมายของ 'one thing' ไม่ชัดเจน จึงแทบไม่ช่วยอะไรในทางปฏิบัติและมีแต่ทำให้เกิดข้อถกเถียง
จะมองว่า Eclipse ก็ 'ทำสิ่งเดียวคือเป็น IDE' ก็ได้ แต่แน่นอนว่านั่นไม่ใช่สิ่งที่นักพัฒนา Unix ตั้งใจจะสื่อ
มันก็ไม่ได้หมายความว่าคุณควรสร้างไลบรารีที่มีแต่ฟังก์ชันยาว 11 บรรทัด
คำแนะนำที่แท้จริงควรเป็นประมาณว่า "อย่าให้โปรแกรมหรือไลบรารีทำมากเกินไปหรือน้อยเกินไป"
และจะถือว่ามากไปหรือน้อยไปแค่ไหน สุดท้ายก็เป็นเรื่องของประสบการณ์และสามัญสำนึก
ขอบคุณ akoculu ที่เขียนบทความนี้
ผมคิดว่าเหตุการณ์นี้เป็นตัวอย่างชัดเจนของชุมชน JavaScript หรือก็คือระบบนิเวศที่พึ่งพา dependencies มากเกินไป
ไม่เข้าใจเหมือนกันว่าทำไมหลายคนถึงโทษคุณขนาดนั้น
คุณก็แค่ unpublish แพ็กเกจที่มีโค้ด 11 บรรทัด และคงไม่ได้คาดการณ์ผลกระทบข้างเคียงทั้งหมดได้ครบถ้วน
ผู้เขียนก็พูดไว้ตรง ๆ ในบทความว่า
ประวัติเวอร์ชันของแพ็กเกจ kik แปลกมาก
เมื่อ 9 ปีก่อนมันถูกแทนที่ด้วย security holding package
ประวัติเวอร์ชันแพ็กเกจ kik
ความประชดที่สุดของเรื่องนี้คือแพ็กเกจ kik
แพ็กเกจ kik ที่ kik อยากได้มากขนาดนั้น สุดท้ายกลับไม่มีประโยชน์อะไรเลย
และบริษัท Kik เองก็กลายเป็นบริษัทที่ดูประมาทและมีปัญหาไม่น้อย
มีทั้งประเด็นคริปโต และยังถูกพูดถึงแบบลับ ๆ ว่าเป็นแพลตฟอร์มที่เกี่ยวข้องกับการกระจายสื่อลามกเด็กเป็นต้น
ดู Darknet Diaries ตอนที่ 93
เพราะงั้นการที่ Azer Koçulu ปฏิเสธ Kik อย่างแข็งกร้าวจึงให้ความรู้สึกสะใจอยู่เหมือนกัน
สรุปแล้วทั้งหมดนี้... สุดท้ายก็ไม่มีความหมายอะไรเลยงั้นหรือ?
แค่การที่ left-pad มีอยู่ในฐานะแพ็กเกจก็ชวนขำมากแล้ว
แค่ฟังก์ชัน padding สตริงตัวเดียว แต่กลับมีไบต์จำนวนมหาศาลวิ่งผ่าน CDN, proxy, build pipeline ฯลฯ
ผมเห็นด้วยกับการใช้โซลูชันที่มีอยู่ให้เป็นประโยชน์ แต่จะคิดว่า "เดี๋ยวก็น่าจะมีแพ็กเกจอยู่แล้วแหละ" สำหรับฟังก์ชันเติมหน้าสตริงง่าย ๆ แบบนี้ มันเข้าใจได้ยากจริง ๆ
ส่วนหนึ่งของข้อถกเถียงในตอนนั้นคือมันทำให้คนตระหนักถึงการยึดติดกับ micro-package แบบไม่ลืมหูลืมตาในหมู่นักพัฒนาเว็บ
มีวัฒนธรรมการปล่อยแพ็กเกจเพื่อเอาความนิยมและ GitHub star ด้วย
อีกด้านหนึ่งก็มีวัฒนธรรมที่ถ้าติดตั้งผ่าน npm ได้ ก็จะไม่ยอมเขียนฟังก์ชันเองไม่ว่าจะเล็กแค่ไหน
นักพัฒนาหลายคนที่ผมทำงานด้วยทุกวันนี้ก็ยังชอบใช้แม้แต่แพ็กเกจง่าย ๆ อยู่มาก
เหตุผลของพวกเขาคือ "ช่วยลดภาระในการบำรุงรักษา"
ช่างเป็นความจริงที่ประชดดี
ดูเหมือนว่าการติดตั้งดั้งเดิมของแพ็กเกจนี้เองก็จะทำให้เกิดการทำงานที่ไม่มีประสิทธิภาพแบบ O(n^2) ไม่ใช่ O(n)
ดูวิกิ
การอ้างอิง utility function จากโปรเจกต์ของคนอื่น กับการใช้แพ็กเกจที่กระจายอยู่ทั่วทั้ง ecosystem แล้ว มีความต่างด้านคุณภาพมากขนาดนั้นหรือ?
มันไม่เหมือนกันเสียทีเดียว แต่ในสภาพแวดล้อมที่มี tooling พัฒนามากพอ ผมคิดว่าสองแนวทางนี้ในทางปฏิบัติก็ไม่ได้ห่างกันนัก
การมุ่งไปให้สุดทางกับการ reuse โค้ด และความยึดติดที่ว่าการ copy-paste เป็นวิธีที่ล้าสมัยไปแล้ว
หรือว่านี่จะคล้ายกับ AI?
ปัญหาที่แก้ได้ด้วยการค้นหาธรรมดา แต่คนก็ยังไปถาม AI ซ้ำอีกพร้อมพรอมป์ต์มหาศาล
เหมือนเพิ่มอีกขั้นตอนที่ไม่จำเป็นให้กับ C&P
ปรัชญา Unix คือ "ทำสิ่งเดียวให้ดี"
left-pad ทำพลาดในเงื่อนไขข้อที่สอง (ให้ดี)
ผมแปลกใจที่มีโปรเจกต์มากขนาดนี้ใช้ implementation แบบตรงไปตรงมานี้กันหมด
implementation ที่ปรับให้ดีกว่านี้อาจทั้งเร็วกว่าและเล็กกว่าด้วยซ้ำ
ผมไม่ค่อยรู้จักวัฒนธรรม JavaScript ดีพอ แต่จำได้ว่ามีกระแสแข่งกันเพิ่มยอดดาวน์โหลด npm
left-pad มียอดดาวน์โหลด 1.4 ล้านครั้งต่อสัปดาห์ ส่วน is-even อยู่ที่ 1.6 แสนครั้ง
บางคนใส่ micro-package เป็น dependency เพื่อความขำ บางคนก็เพื่อเพิ่มตัวชี้วัดความนิยมของไลบรารี
ยังเคยมีเสียงคัดค้านการใส่แพ็กเกจอย่าง is-even ไว้ในไลบรารีดังที่สร้างบน react อยู่เหมือนกัน
เพราะมีหลักการเคร่งครัดแบบ "ถ้าดึงมาใช้ได้ก็ต้องดึงมา อย่าเขียนเอง"
เรื่องที่เกี่ยวข้อง: ทำไมแพ็กเกจ is-odd ถึงถูกติดตั้งเกือบ 3 ล้านครั้งในหนึ่งสัปดาห์
อยากเห็นตัวอย่างของ 'implementation ที่ไม่ตรงไปตรงมา (nonnaive implementation)'
ผมเป็นเมนเทนเนอร์ของแพ็กเกจ npm ยอดนิยม
รู้สึกอินมาก
npm ค่อย ๆ ห่างออกจากการร่วมมือแบบคอมมูนิตี้ตั้งแต่ช่วงหนึ่ง
พอถูก Microsoft ซื้อไปก็ยิ่งแข็งตัวขึ้น แต่ก่อนหน้านั้นก็มีสัญญาณมาเยอะแล้ว
วิธีดำเนินงานหลายอย่างของ npm ท่าทีที่ไม่ค่อยร่วมมือกับคอมมูนิตี้/ทีม Node การมุ่งเน้นเชิงพาณิชย์มากเกินไป ชื่อเสียงของสมาชิกบางคน ฯลฯ มีหลายอย่างที่ชวนขัดใจ
ผมยังจำได้ว่าเคยไปที่ออฟฟิศ Oakland และปฏิสัมพันธ์ในวันนั้นก็ไม่ได้ดีนัก เลยจะไม่ลงรายละเอียด
ช่องโหว่ของ unpublish เป็นปัญหาที่ทุกคนรู้กันอยู่แล้วในตอนนั้น
ทุกคนพูดกันแค่ว่า 'left-pad ทำอินเทอร์เน็ตพัง' แล้วก็โทษผู้เขียนคนเดียว แต่ผมคิดว่าปัญหาจริงคือการบริหารที่หละหลวมของ npm
ถ้าจำไม่ผิด พวกเขาฝืนกู้แพ็กเกจกลับมาทั้งที่ขัดกับความต้องการของเมนเทนเนอร์เอง ซึ่งเป็นการตัดสินใจที่แยกขาดจากระดับคอมมูนิตี้ที่ npm อ้างว่าเป็นตัวแทนอย่างสิ้นเชิง (อย่างน้อยในทางกฎหมายก็ดูแปลก)
หลังจากนั้น npm ก็แทบไม่สนใจเรื่องการจัดการ abuse, spam ฯลฯ (อย่างโฆษณาสแปมของ core.js) และแทบไม่เข้าร่วมการพูดคุยมาตรฐานหรือ compatibility กับคอมมูนิตี้เลย
การออก npm@5 ก็ล้มเหลวอย่างมาก และการนำ package lockfile เข้ามาก็เป็นเรื่องวุ่นวาย
(ที่ทีม Node ปล่อยออกไปโดยไม่รอให้ npm พร้อม กลับดูเป็นการตัดสินใจที่ดีเสียด้วยซ้ำ)
ตอนนั้นการสื่อสารกับคอมมูนิตี้เต็มไปด้วยบั๊กใหญ่ การโทษคอมมูนิตี้ และท่าทีแบบกดหัว
เป็นหลักฐานว่า npm ไม่ได้เป็นตัวแทนของจิตวิญญาณโอเพนซอร์สอีกต่อไป
ผมจำไม่ค่อยได้แล้วว่า left-pad มาก่อนหรือหลังเรื่องนั้น แต่ตอนนั้นทั้ง ecosystem อยู่ในช่วงซบเซาและสับสนระยะยาว
แพ็กเกจ npm มักถูกล้อว่าเป็นแพ็กเกจเดี่ยวสำหรับฟังก์ชันจิ๊บจ๊อย แต่ถ้ามองตามบริบท npm คือ package manager ที่เข้าถึงง่ายตัวแรกสำหรับ emergent popular technology และเป็นระบบที่ขับเคลื่อนโดยคอมมูนิตี้พร้อมเชื่อมกับ Github อย่างแนบแน่น
มันเกิดขึ้นในยุคแรกของ Node ตอนที่ยังไม่มี ES5 และยังใช้
var,prototypeกันอยู่ ก่อนที่ Joyent จะส่งมอบ Node.js ให้คอมมูนิตี้เสียอีก และก่อนการ fork เป็น Io.js กับช่วงชะงักยาวของ Node 0.10/0.12เป็นยุคที่ยังไม่มีใครรู้ชัดว่าควรทำ best practice แบบไหน
ผมเข้าใจมุมของผู้เขียนมากจริง ๆ
ถ้ามองด้านความปลอดภัย เหตุการณ์ left-pad กลายเป็นการปลุกให้วงการตระหนักครั้งใหญ่ถึงความจริงที่ว่าบริษัท/ชุมชนใน ecosystem นี้แยกจากกัน และยังทำให้ supply chain security เป็นประเด็นสำคัญ
มันจุดประกายการพูดคุยสำคัญเรื่อง redundancy และความปลอดภัย
ผมคิดว่าสุดท้ายแล้วมันทำให้อุตสาหกรรมดีขึ้น
กลับมาอ่านอีกครั้งหลังจากนานมากก็ยังน่าสนใจ
npm ไม่ใช่ package manager ตัวแรกของภาษาใด ๆ และก็มีคนเตือนเรื่องแพ็กเกจเล็กจิ๋วมากมายแบบนี้มานานแล้ว
ผมคิดว่า npm และ ecosystem ของ JS โดยรวมเป็นเหยื่อของกระแสเทรนด์
การถกเถียงที่เกี่ยวข้องในยุค left-pad
การสนทนาบน Hacker News
ทำไม Java ถึงมี utility library ที่น่าเชื่อถืออย่าง Apache Commons, Google Guava แต่ JS ไม่มีแบบนั้น?
JavaScript ก็มี utility library ที่เชื่อถือได้อย่าง Lodash และทุกวันนี้ฟังก์ชันส่วนใหญ่ก็เข้าไปอยู่ใน standard library แล้ว
จริง ๆ แล้ว Lodash มีฟังก์ชัน pad/padStart/padEnd ตั้งแต่ 3 เดือนก่อนเหตุการณ์ left-pad ด้วยซ้ำ
เอกสาร Lodash pad
ผมคิดว่าสาเหตุสำคัญที่สุดเรียงตามลำดับคือ วัฒนธรรม, standard library ที่ออกแบบมาดี และการมีหรือไม่มีเครื่องมือที่ช่วยป้องกันไม่ให้ยัดแพ็กเกจไร้ประโยชน์กว่า 300 ตัวเข้าไปเป็น dependency
Maven เป็นเครื่องมือที่ออกแบบมาดีมากจริง ๆ (น่าประชดตรงที่โดนด่าตลอด) และเป็นหนึ่งในเคล็ดลับความสำเร็จของ Java
เหตุผลที่ไม่มีการประนีประนอมเชิงพาณิชย์แบบ npm ก็เพราะ Java มี Apache Foundation ซึ่งเป็นองค์กรไม่แสวงกำไรและขับเคลื่อนโดยคอมมูนิตี้ที่ได้รับการสนับสนุนอย่างดี (โครงสร้างแบบนี้หาได้ยากมาก และเป็นผลลัพธ์แบบโชคดีจากประวัติทางกฎหมายอันซับซ้อนของ Java)
(JS เองก็มีไลบรารีดี ๆ มากมาย ปัญหาคือการจัดการแพ็กเกจรวมศูนย์เกินไปและกำกับดูแลได้ไม่ดี)
Google Guava คล้าย lodash มากกว่า และไม่เหมือน left-pad
เมื่อก่อนมีไลบรารีอย่าง Jquery, Underscore ที่ทำหน้าที่นั้น
ผมรู้สึกแปลกใจมากที่ยังมีบริษัทจำนวนมากไม่ mirror dependencies ทั้งหมดที่ต้องใช้ในการ build ไว้ภายในองค์กร
กระบวนการ build ทั้งหมดควร clean build แบบออฟไลน์ได้ และการพึ่งแค่ download cache ก็เหมือนปล่อยให้โชคชะตาตัดสิน
โปรเจกต์ของผมจะ vendor dependencies ไว้ข้างในเสมอ
คาดเดาได้ สร้างแบบออฟไลน์ได้ และค่าใช้จ่ายด้านพื้นที่เก็บข้อมูลก็ถูกมาก