10 คะแนน โดย GN⁺ 2026-03-23 | 2 ความคิดเห็น | แชร์ทาง WhatsApp
  • ในระบบนิเวศ npm ปัญหาใหญ่ที่ถูกชี้ให้เห็นคือ การพองตัวของ dependency tree ซึ่งเกิดจากการรองรับรันไทม์เก่า โครงสร้างแพ็กเกจแบบอะตอม และการใช้ ponyfill ที่ล้าสมัย
  • แพ็กเกจยูทิลิตีขนาดเล็กที่ยังคงอยู่ด้วยเหตุผลด้านความเข้ากันได้กับเอนจินรุ่นเก่าและ ความปลอดภัยข้าม realm ยังคงหลงเหลือโดยไม่จำเป็นแม้ในสภาพแวดล้อมสมัยใหม่
  • สถาปัตยกรรมแบบอะตอม ถูกออกแบบมาเพื่อเพิ่มการนำกลับมาใช้ซ้ำ แต่ในทางปฏิบัติกลับกลายเป็นโครงสร้างที่ไม่มีประสิทธิภาพซึ่งเพิ่มต้นทุนด้านความซ้ำซ้อน ความปลอดภัย และการบำรุงรักษา
  • แพ็กเกจ ponyfill ที่ล้าสมัย สำหรับฟีเจอร์ที่ทุกเอนจินรองรับอยู่แล้วไม่ได้ถูกลบออก ส่งผลให้เกิดภาระการดาวน์โหลดและการจัดการโดยไม่จำเป็น
  • ชุมชนกำลังผลักดัน การจัดระเบียบ dependency ที่ไม่จำเป็นและการเปลี่ยนไปใช้ความสามารถแบบเนทีฟ ผ่านเครื่องมืออย่าง e18e, knip และ module-replacements

สามแกนของภาวะพองตัวของ dependency ใน JavaScript

  • พร้อมกับการเติบโตของ ชุมชน e18e การมีส่วนร่วมที่เน้นประสิทธิภาพก็เพิ่มขึ้น และมีการทำ cleanup เพื่อลบแพ็กเกจที่ไม่จำเป็นหรือไม่มีการดูแลแล้ว
  • ในระบบนิเวศ npm ปัญหาใหญ่ที่ถูกชี้ให้เห็นคือ ภาวะพองตัวของ dependency tree (dependency bloat) โดยมีสาเหตุหลักจากการรองรับรันไทม์เก่า โครงสร้างแพ็กเกจแบบอะตอม และการใช้ ponyfill ที่ล้าสมัย

1. การรองรับรันไทม์เก่า (รวมถึงความปลอดภัยและ realm)

  • ใน npm tree มี แพ็กเกจยูทิลิตีขนาดเล็ก จำนวนมาก เช่น is-string, hasown ซึ่งยังคงอยู่ด้วยเหตุผลสามประการต่อไปนี้
    • รองรับเอนจินที่เก่ามาก (เช่น ES3, IE6/7, Node.js ยุคแรก)
    • การป้องกันการดัดแปลง global namespace

      • การจัดการค่าข้าม realm
  • การรองรับเอนจินเก่า

    • ในสภาพแวดล้อม ES3 ไม่มี ฟีเจอร์ของ ES5 เช่น Array.prototype.forEach, Object.keys, Object.defineProperty
    • ในสภาพแวดล้อมเหล่านี้ต้องเขียนเองโดยตรงหรือใช้ polyfill
    • ทางออกที่ดีที่สุดคือ อัปเกรด แต่ผู้ใช้บางส่วนยังคงใช้เวอร์ชันเก่าอยู่
  • การป้องกันการดัดแปลง global namespace

    • ภายใน Node ใช้แนวคิด primordials โดยห่ออ็อบเจ็กต์ global ตั้งแต่ช่วงเริ่มต้นเพื่อป้องกันการดัดแปลง
    • ตัวอย่างเช่น หากมีการ override Map ตัว Node เองอาจทำงานพังได้ ดังนั้น Node จึงเก็บ reference ต้นฉบับไว้
    • ผู้ดูแลแพ็กเกจบางรายนำแนวทางนี้มาใช้กับแพ็กเกจทั่วไปด้วย โดยใช้ แพ็กเกจที่เน้นความปลอดภัย อย่าง math-intrinsics
  • ค่าข้าม realm

    • เมื่อส่งอ็อบเจ็กต์ข้าม iframe จะเกิดปัญหาที่การตรวจ instanceof ล้มเหลว
    • ตัวอย่าง: window.RegExp !== iframeWindow.RegExp
    • เฟรมเวิร์กทดสอบอย่าง chai ใช้วิธี Object.prototype.toString.call(val) เพื่อตรวจชนิดข้าม realm
    • แพ็กเกจอย่าง is-string จึงมีอยู่เพื่อรองรับ ความเข้ากันได้ข้าม realm
  • ปัญหา

    • นักพัฒนาส่วนใหญ่ใช้ Node รุ่นใหม่หรือเบราว์เซอร์ evergreen อยู่แล้ว ทำให้ความเข้ากันได้แบบนี้ไม่จำเป็น
    • แต่แพ็กเกจเหล่านี้กลับอยู่ใน “hot path” ของ dependency tree ทั่วไป ทำให้ ทุกคนต้องจ่ายต้นทุน

2. สถาปัตยกรรมแบบอะตอม (Atomic)

  • นักพัฒนาบางส่วนเชื่อว่าควรแยกแพ็กเกจออกเป็น หน่วยที่เล็กที่สุดเท่าที่จะทำได้ เพื่อสร้างเป็น building blocks ที่นำกลับมาใช้ซ้ำได้
  • ผลลัพธ์คือมีแพ็กเกจที่แยกย่อยอย่างมากจำนวนมาก เช่น shebang-regex, arrify, slash, path-key, onetime, is-wsl
  • ตัวอย่าง: shebang-regex มีเพียง regex บรรทัดเดียว (/^#!(.*)/)
  • ปัญหา

    • แพ็กเกจแบบอะตอมส่วนใหญ่ ไม่ได้ถูกนำกลับมาใช้ซ้ำ หรือมีผู้ใช้เพียงรายเดียว
    • ตัวอย่าง:
      • shebang-regex → ใช้โดย shebang-command เท่านั้น
      • cli-boxes → ใช้โดย boxen, ink เท่านั้น
      • onetime → ใช้โดย restore-cursor เท่านั้น
    • ในกรณีเหล่านี้มันแทบไม่ต่างจากการเขียนโค้ด inline แต่กลับมีต้นทุนเพิ่มจาก คำขอ npm, การแตกไฟล์, แบนด์วิดท์ เป็นต้น
  • ปัญหาความซ้ำซ้อน

    • ตัวอย่าง: ใน dependency tree ของ nuxt@4.4.2 มี is-docker, is-stream, is-wsl, path-key ซ้ำกันอย่างละ 2 เวอร์ชัน
    • หากแทนที่ด้วยโค้ด inline ก็จะไม่มีทั้งปัญหาความขัดแย้งของเวอร์ชันและต้นทุนการ resolve ทำให้ ต้นทุนจากความซ้ำซ้อนแทบหายไป
  • ความเสี่ยงของซัพพลายเชนที่เพิ่มขึ้น

    • ยิ่งมีจำนวนแพ็กเกจมากเท่าไร ความเสี่ยงด้านความปลอดภัยและการบำรุงรักษา ก็ยิ่งเพิ่มขึ้น
    • เคยมีกรณีจริงที่ผู้ดูแลคนหนึ่งดูแลแพ็กเกจขนาดเล็กจำนวนมาก แล้วบัญชีถูกแฮ็กจนทำให้ แพ็กเกจนับร้อยเสียหายพร้อมกัน
    • โค้ดง่าย ๆ อย่าง Array.isArray(val) ? val : [val] สามารถเขียน inline ได้โดยไม่จำเป็นต้องแยกเป็นแพ็กเกจ
  • บทสรุป

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

3. Ponyfill ที่ล้าสมัย

  • Polyfill คือโค้ดที่เพิ่มความสามารถให้กับสภาพแวดล้อมเมื่อเอนจินยังไม่รองรับฟีเจอร์นั้น ส่วน Ponyfill คืออิมพลีเมนเทชันทดแทนที่ import มาใช้โดยตรง โดยไม่แก้ไขสภาพแวดล้อม
  • ตัวอย่าง: @fastly/performance-observer-polyfill มีทั้ง polyfill และ ponyfill
  • ปัญหา

    • Ponyfill เคยมีประโยชน์ในอดีต แต่ แม้ฟีเจอร์เป้าหมายจะถูกรองรับโดยทุกเอนจินแล้วก็ยังไม่ถูกลบออก
    • ตัวอย่าง:
      • globalthis (รองรับตั้งแต่ปี 2019, ดาวน์โหลด 49 ล้านครั้งต่อสัปดาห์)
      • indexof (รองรับตั้งแต่ปี 2010, ดาวน์โหลด 2.3 ล้านครั้งต่อสัปดาห์)
      • object.entries (รองรับตั้งแต่ปี 2017, ดาวน์โหลด 35 ล้านครั้งต่อสัปดาห์)
    • แพ็กเกจเหล่านี้ส่วนใหญ่ยังคงอยู่ เพียงเพราะไม่เคยถูกลบออก
    • เมื่อเอนจิน LTS ทุกตัวรองรับฟีเจอร์นั้นแล้ว ก็ควรถอด ponyfill ออก

แนวทางลดภาวะพองตัว

  • ด้วยความที่ dependency tree ซ้อนลึกมาก การจัดระเบียบจึงทำได้ยาก แต่สามารถปรับปรุงได้ผ่านความร่วมมือของชุมชน
  • นักพัฒนาแต่ละคนควรถามตัวเองว่า “แพ็กเกจนี้จำเป็นจริงหรือไม่?” และหากไม่จำเป็นก็ควร เปิด issue หรือมองหาแพ็กเกจทดแทน
  • โปรเจกต์ module-replacements ให้ รายชื่อแพ็กเกจที่สามารถแทนด้วยความสามารถแบบเนทีฟได้
  • การใช้ knip

    • knip เป็น เครื่องมือสำหรับตรวจจับ dependency ที่ไม่ได้ใช้และโค้ดที่ตายแล้ว
    • แม้จะไม่ใช่คำตอบโดยตรง แต่ก็มีประโยชน์ในฐานะ จุดเริ่มต้นของการ cleanup
  • การใช้ e18e CLI

    • สามารถใช้คำสั่ง @e18e/cli analyze เพื่อ ตรวจหา dependency ที่สามารถแทนที่ได้
    • ตัวอย่าง: ย้ายจาก chalk ไปเป็น picocolors แบบอัตโนมัติ
    • ในอนาคตมีแผนจะแนะนำ ความสามารถแบบเนทีฟอย่าง styleText ของ Node ตามสภาพแวดล้อมด้วย
  • การใช้ npmgraph

    • npmgraph.js.org เป็น เครื่องมือแสดงภาพ dependency tree
    • ตัวอย่าง: ใน tree ของ eslint@10.1.0 จะเห็นว่าแขนง find-up ถูกแยกโดดเดี่ยวอยู่
    • ฟังก์ชันค้นหาไฟล์แบบง่าย ๆ ไม่ควรต้องใช้ถึง 6 แพ็กเกจ ดังนั้นจึงอาจใช้ทางเลือกที่เล็กกว่าอย่าง empathic ได้
  • โปรเจกต์ module replacements

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

บทสรุป

  • ภาวะพองตัวในปัจจุบันคือโครงสร้างที่ทำให้ทุกคนต้องจ่ายต้นทุน เพราะมีผู้ใช้ส่วนน้อยที่ยังต้องการ ความเข้ากันได้กับของเก่าและโครงสร้างเฉพาะทาง
  • แม้ในอดีตจะหลีกเลี่ยงไม่ได้ แต่ เมื่อเอนจินและ API สมัยใหม่พัฒนามากพอแล้ว ภาระนี้ก็ไม่จำเป็นอีกต่อไป
  • ต่อจากนี้ ผู้ใช้ส่วนน้อยเหล่านั้นอาจต้องดูแลสแตกแยกต่างหาก ส่วนคนส่วนใหญ่ควรเปลี่ยนไปสู่ ฐานโค้ดที่เบาและทันสมัย
  • โปรเจกต์อย่าง e18e และ npmx กำลังสนับสนุนเรื่องนี้ผ่านการจัดทำเอกสารและเครื่องมือ และนักพัฒนาแต่ละคนก็ควรตรวจสอบ dependency ของตนเอง พร้อมถามว่า “จำเป็นเพราะอะไร?”
  • ทุกคนช่วยกันจัดระเบียบได้

2 ความคิดเห็น

 
click 2026-03-23

ตอนที่ผมทำไลบรารีเองก็ยังคงมีการแจกจ่าย cjs build อยู่เหมือนกัน
แต่ก็อยากให้ไลบรารีที่แม้แต่ในปี 2026 ก็ยังไม่มีตัวอย่าง esm และทั้งหมดอิงกับ require ล้วนอัปเดตกันสักหน่อย

 
GN⁺ 2026-03-23
ความคิดเห็นจาก Hacker News
  • ช่วงนี้ผมคิดว่าทิศทางที่ดีที่สุดคือการพัฒนาด้วย JavaScript ที่ไม่มี dependency
    ทั้งไลบรารีมาตรฐานของ JS/CSS, การวิเคราะห์แบบสถิต (การตรวจ JSDoc ของ TypeScript), ES modules, เว็บคอมโพเนนต์ ก็ทรงพลังเพียงพอแล้ว
    คนมักบอกว่าวิธีนี้ไม่เหมาะกับการขยายระบบหรือการดูแลรักษา แต่จากประสบการณ์ของผมกลับทำให้รักษาโครงสร้างที่เรียบง่ายและแก้ไขเปลี่ยนแปลงได้ง่ายกว่า

    • ผมเองก็ทดลองแนวทางนี้มาหลายปีแล้ว และยังทำเว็บสอนชื่อ plainvanillaweb.com ขึ้นมาด้วย
      สิ่งที่เฟรมเวิร์กหรือ build tool ทำอยู่ส่วนใหญ่สามารถแทนที่ได้ด้วยความสามารถที่มีอยู่ในเบราว์เซอร์และ vanilla pattern
      แต่ปัญหาคือแนวทางนี้ยังเป็นพื้นที่ที่ไม่ค่อยคุ้นเคย ทำให้ระบบนิเวศของบทเรียนส่วนใหญ่ยังหมุนรอบเฟรมเวิร์กขนาดใหญ่
      จริง ๆ แล้วต่อให้ย้ายโค้ด React มาเป็น vanilla ล้วน ๆ ก็ยังรักษาความเป็นโมดูลาร์ไว้ได้ และโค้ดยาวขึ้นแค่ราว 1.5 เท่า แต่เพราะไม่มี dependency ประสิทธิภาพกลับดีกว่า
      แน่นอนว่าไม่ได้หมายความว่า dependency เป็นสิ่งไม่ดี แค่มีนักพัฒนาจำนวนมากติดอยู่กับ กรอบความคิดตายตัว ว่า “จำเป็นต้องใช้”
    • ถ้าเป็นหน้า marketing ง่าย ๆ ก็พอเป็นไปได้ แต่ถ้าเป็นแอปที่มีฟีเจอร์เยอะ หลายครั้ง dependency ก็เป็นสิ่งจำเป็น
      ตัวอย่างเช่นผมทำเว็บที่มีความสามารถด้านแผนที่เยอะ จึงต้องใช้ไลบรารีอย่าง mapbox/maplibre/openlayers ที่แทบไม่มีตัวเลือกทดแทน
    • ผมทำโปรเจ็กต์ด้วยแนวทางนี้ในปี 2022 และไม่เจอปัญหาเรื่อง CVE หรือการย้ายเวอร์ชันเลย
      ลูกค้าก็ไม่ต้องจ่ายค่าการย้ายระบบแม้แต่บาทเดียว
    • การเรนเดอร์คอมโพเนนต์นั้นง่าย แต่หัวใจของเฟรมเวิร์กคือการให้ การอัปเดตเชิง reactive ของโมเดล
      ผมเลยสงสัยว่าเขาจัดการการอัปเดตโมเดลอย่างไร ตามที่พูดไว้ในบทความนี้
    • ผมทำงานกับ JS มาเกือบ 20 ปีแล้ว สุดท้ายก็ลงเอยที่ใช้ dependency ให้น้อยที่สุด แล้วที่เหลือทำเอง
      กลับกลายเป็นว่าการดูแล codebase ขนาดใหญ่ ด้วยทีมเล็กทำได้สะดวกกว่า
      ด้วยเครื่องมือสมัยนี้ การทำเองง่ายกว่าเมื่อก่อนมาก และยังเข้ากับ agentic engineering ได้ดีด้วย
  • บทความนี้เขียนดี และอธิบายปัญหาได้ชัดโดยไม่ใช้อารมณ์
    ผมคิดว่าส่วนหนึ่งของสาเหตุคือ JS ยังไม่มี “standard library” ที่สมบูรณ์จริง ๆ

    • เดี๋ยวนี้ standard library ของ JS ก็ใหญ่พอสมควรแล้ว เลยอยากรู้ว่ายังมองว่าขาดอะไรอยู่บ้าง
    • ส่วนตัวผมกลับชอบ บทความแนว rant เพราะมันช่วยให้เข้าใจไม่ใช่แค่อารมณ์ของผู้คน แต่รวมถึงเหตุผลเบื้องหลังด้วย
  • เป็นบทความที่ดี แต่ผมคิดว่ารากของปัญหาจริง ๆ คือ การเพิ่มสิ่งที่ไม่จำเป็น (=bloat)
    อยากยกคำพูดของแซงเต็กซูเปรีที่ว่า “ความสมบูรณ์แบบไม่ได้เกิดขึ้นเมื่อไม่มีอะไรให้เพิ่มอีก แต่เกิดขึ้นเมื่อไม่มีอะไรให้ตัดออกอีก”
    ซอฟต์แวร์ส่วนใหญ่ถูกเขียนโดยตั้งคำถามว่า “จะเพิ่มอะไรได้ง่ายขึ้นอย่างไร?” มากกว่า “จะทำให้มันงดงามขึ้นอย่างไร?”
    และคำตอบก็มักเป็น npm i more-stuff เสมอ

    • มันทำให้นึกถึงกฎการเขียนของเคิร์ต วอนเนอกัตที่ว่า “ทุกประโยคควรเผยให้เห็นตัวละครหรือทำให้การกระทำเดินหน้า”
      เหมือนกับการเปรียบเทียบระหว่าง เดโมสเทเนสกับซิเซโร โค้ดที่ดีคือโค้ดที่ตัดอะไรออกไม่ได้อีกแล้ว
    • ซอฟต์แวร์ทุกตัวมีส่วนที่ไม่จำเป็นอยู่บ้าง แต่ npm package และเว็บแอปเป็นกรณีที่หนักเป็นพิเศษ
      JS ต้องคำนึงถึงทั้งความเข้ากันได้กับเบราว์เซอร์เก่าและอนาคต อีกทั้งเป็นภาษาที่เน้น UI จึงทำให้ ตัวระบบพองใหญ่ขึ้น จากเรื่อง accessibility, internationalization, การรองรับมือถือ ฯลฯ
  • หลายกรณีดูเหมือนนี่คือปัญหา หนี้ทางเทคนิค ที่ซ่อนอยู่
    สาเหตุมาจากการไม่อัปเดต compile target ไปเป็น ESx ที่ใหม่ขึ้น และไม่อัปเดตแพ็กเกจหรือ implementation
    ES5 รองรับในทุกเบราว์เซอร์มาแล้ว 13 ปี (caniuse.com/es5)

    • ในโลกจริงยังมีทั้งคนที่พยายามรองรับ JS engine รุ่นเก่า และคนที่สร้าง แพ็กเกจจิ๋ว จำนวนมาก
      ทั้งสองกลุ่มมองว่าสิ่งที่ตัวเองทำคือฟีเจอร์ และยังดูแลแพ็กเกจยอดนิยมจำนวนมาก
      เลยทำให้เปลี่ยนแปลงได้ยาก แม้บางครั้งชุมชนจะวิจารณ์ แต่พวกเขาก็มีเหตุผลในแบบของตัวเอง
    • ความพยายามจะคงความเข้ากันได้ต่ำกว่า ES6 ฟังดูแปลก ๆ
      ถ้า transpile ลงไปเป็นเวอร์ชันเก่าด้วย Babel โค้ดจะ ใหญ่และช้าลง และสุดท้ายก็ยังใช้ไม่ได้บนเบราว์เซอร์เก่าเพราะข้อจำกัดของ CSS หรือฟีเจอร์ JS อยู่ดี
      แถมเคยมีกรณีที่ polyfill ก่อปัญหาด้วยซ้ำ (polyfill ของ exponent operator ที่จัดการ BigInt ไม่ได้)
    • ไม่ใช่แค่เบราว์เซอร์เก่า แต่ยังต้องรองรับ เบราว์เซอร์แปลก ๆ ด้วย
      มีทั้งคอนโซล, ทีวี, Android รุ่นเก่า, iPod touch, เบราว์เซอร์ฝังใน Facebook และสภาพแวดล้อมอีกหลากหลาย
      เพราะงั้นผมเลยมี external module แค่ตัวเดียว แล้วปล่อยให้ที่เหลือจัดการด้วยการตั้งค่า transpiler
    • เว็บมีวัฒนธรรมแบบ “ปล่อยตอนนี้แล้วค่อยแก้ทีหลัง” แรงมาก ทำให้ dependency เก่า ค้างอยู่นาน
    • อย่างการตัดสินใจออกแบบของ Angular ก็เป็นตัวอย่างที่โครงสร้างในอดีตนำไปสู่ ความไม่มีประสิทธิภาพ ในปัจจุบัน
      เมื่อก่อนต้อง override setTimeout อะไรทำนองนั้นเพื่อติดตาม async แต่ตอนนี้จัดการได้ง่ายกว่ามากด้วย signals
  • ผมคิดว่าผู้เขียนแพ็กเกจบางคน จงใจแยก dependency tree ออกเป็นชิ้นเล็ก ๆ เพื่อเพิ่มยอดดาวน์โหลด
    การมีแพ็กเกจยาว 7 บรรทัดมันไร้สาระมาก ขนาด metadata ใน lockfile ยังใหญ่กว่าโค้ดเสียอีก
    เมื่อก่อน 5% ของ dependency ใน create-react-app มาจากมินิแพ็กเกจของผู้เขียนคนเดียว
    มีตัวอย่างอย่าง has-symbols, is-string, ljharb

    • ผมสงสัยว่านี่เป็นแค่เรื่อง อีโก้ หรือมีผลประโยชน์จริง ๆ กันแน่
      อย่างเช่น Anthropic ให้ Claude ฟรี แก่นักดูแลโอเพนซอร์สที่มียอดดาวน์โหลด npm สูง
    • อย่างในบทความ immich.app/cursed-knowledge ก็มีคนเพิ่มถึง 50 แพ็กเกจโดยอ้างเรื่อง “backward compatibility”
    • ในแง่ความปลอดภัยก็ร้ายแรงเหมือนกัน เพราะ micro-package พวกนี้แต่ละตัวคือพื้นผิวการโจมตีเพิ่มขึ้น
      การแข่งขันเรื่องยอดดาวน์โหลดยิ่งทำให้ความเสี่ยงสูงขึ้น
    • เมื่อก่อนเคยมีคนแทรกตัวเข้าไปในองค์กรแล้วเพิ่มแพ็กเกจของตัวเองเข้าไปใน dependency เพื่อปั่น จำนวนดาวสำหรับใส่ในเรซูเม่ ด้วย
    • มันยังเป็นปัญหาเชิงวัฒนธรรมด้วย ในชุมชน JS การคัดลอกโค้ด 7 บรรทัดมาติดเองมักถูกตำหนิว่าเป็น “การประดิษฐ์ล้อขึ้นใหม่
      แต่ในวัฒนธรรมอื่นกลับมองว่านั่นเป็นเรื่องที่ดีกว่าเสียอีก
  • ก่อนจะวิจารณ์ ecosystem ของ JS ผมว่าไปอ่าน 30 years of br tags ก่อนก็ดี
    จะช่วยให้เข้าใจ กระบวนการวิวัฒนาการ ของ JS และเครื่องมือรอบตัวมัน
    การพูดแค่ว่า “ปัญหาคือพวกนักพัฒนา JS” เป็นการขาดวิธีคิดแบบวิศวกรรม

    • การพยายามทำความเข้าใจกับความจริงที่ไม่ดีเป็นเรื่องที่ดี แต่ การยอมรับมากเกินไป ก็คือความพ่ายแพ้
      เราควรคิดถึงทฤษฎีและแนวปฏิบัติที่ดีกว่าอยู่เสมอ
      โลกของซอฟต์แวร์เปลี่ยนเร็ว จึงควรจัด “พิธีศพปลอม” ให้ตัวเองเป็นระยะเพื่อทิ้งแนวปฏิบัติเก่า ๆ
    • สำหรับผม บทความนี้ไม่ได้โทษนักพัฒนา แต่เป็นการ วิจารณ์สภาพปัจจุบันอย่างมีเหตุผล มากกว่า
  • ผมกำลังดูแล codebase Node.js ที่มีอายุ 9 ปี ซึ่งมี dependency แค่ 8 ตัว และทั้งหมด ไม่มี dependency ย่อย
    ผมใช้ความสามารถที่มีมาใน Node ก่อน แล้วค่อยเขียนเองเฉพาะส่วนที่จำเป็น
    มันเสถียรกว่าเดิมมากและเครียดน้อยกว่ามาก
    standard library ของ Deno ก็ยอดเยี่ยมเช่นกัน ถ้าใช้ร่วมกับความสามารถพื้นฐานของ runtime ก็สร้างแอปได้ด้วยแพ็กเกจไม่กี่ตัว
    JS เป็น ภาษาที่ดีพอสมควรถ้าใช้อย่างระมัดระวัง

  • ผมเข้าใจข้ออ้างเรื่อง ความปลอดภัยข้าม realm ของแพ็กเกจอย่าง is-string แต่ในความเป็นจริงสถานการณ์แบบนั้นพบไม่บ่อย
    ปัญหาคือ npm เปิดให้เผยแพร่ได้ง่ายเกินไป จนปรัชญาแบบ “แยกโมดูลแล้วเผยแพร่” ถูก ขยายเกินขอบเขต
    ผู้ใช้ไม่ค่อย audit dependency tree และมักติดตั้งเลยทันที ทำให้ต้นทุนที่ควรเป็นทางเลือกกลายเป็นต้นทุนพื้นฐานไป
    ปัญหา ponyfill น่าจะแก้ได้ด้วยระบบอัตโนมัติ
    เช่น อาจมี บอตสไตล์ Renovate ที่ตรวจจับอัตโนมัติและลบฟีเจอร์ที่มีรองรับอยู่แล้วใน Node LTS

  • หลักการของ PWA ภายในบริษัทเรามีแค่อย่างเดียว:
    อัปเกรดเป็น Chrome เวอร์ชันล่าสุด ถ้ายังมีปัญหาค่อยว่ากัน”

    • ถ้าเป็นระบบใช้ภายใน นี่เป็นแนวทางที่ถูกต้องแล้ว บริษัทกำหนดเบราว์เซอร์ที่รองรับได้ก็จัดการง่าย
      ผมเข้าใจว่า Safari ใช้หน่วยความจำน้อยกว่า แต่การกำหนดให้เป็นมาตรฐานเดียวกันในเชิงนโยบายมีประสิทธิภาพกว่า
    • การทำให้เรียบง่ายสุดท้ายแล้วให้ ผลประโยชน์มากที่สุด
  • คำพูดที่ว่า “ต้องรองรับถึง ES3 (ระดับ IE6/7)” นี่เข้าใจยากจริง ๆ
    ในเชิงความปลอดภัย แม้แต่เว็บธนาคารก็ควรบล็อกเบราว์เซอร์โบราณแบบนั้น

    • ทีมแบบนี้ส่วนมากคือพวกที่ ยังไม่เคยเปลี่ยน build tool ที่ตั้งไว้ราวปี 2015
      การอัปเกรด Webpack, Babel, polyfill stack เป็นงานใหญ่ เลยปล่อยค้างไว้อย่างนั้น
      เป็นวัฒนธรรมแบบ “ถ้ายังไม่พังก็อย่าไปแตะมัน”
    • ในความเป็นจริงก็มี บุคคลบางคน ที่ผลักดันการรองรับของเก่าแบบนี้ และเขาก็ดูแลแพ็กเกจระดับล่างไว้จำนวนมาก
    • แล้วก็ได้ยินมาว่า Deutsche Bahn ยังใช้งาน Windows 3.1 อยู่เลย