3 คะแนน โดย GN⁺ 2023-07-03 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • นักพัฒนา JavaScript ที่มีประสบการณ์ 10 ปีใช้ฉากการอ่าน package.json เป็น บททดสอบแห่งความเจ็บปวด เพื่อแสดงให้เห็นว่าไฟล์ตั้งค่าเพียงไฟล์เดียวบรรจุความซับซ้อนสะสมของ ecosystem ไว้มากเพียงใด
  • ฟิลด์อย่าง main, browser, type: module ทำให้นึกถึงบาดแผลจาก migration เก่า ๆ ของ Isomorphic JavaScript, browser bundle และการเปลี่ยนผ่านระหว่าง CommonJS กับ ESM
  • ใน scripts, dependencies, devDependencies มีเครื่องมือเก่าและปัญหาการจัดการแพ็กเกจพันกันอยู่ เช่น lint หลายรูปแบบ, watchman, gulp, left-pad, moment.js, resolutions
  • eslint, postcss, jest รวมถึงเครื่องมือ build/test ต่าง ๆ เพิ่ม ต้นทุนการดูแลรักษา development environment ผ่านกฎที่เข้มงวด, ข้อผิดพลาดการติดตั้งเฉพาะแพลตฟอร์ม และความยากในการตั้งค่า ESM/TypeScript
  • แม้จะเห็น Node engines ก็ยังไม่ย้ายไป Bun หรือ Deno เพราะเชื่อว่าความเจ็บปวดจะไม่หายไป แต่จะยิ่งมากขึ้น นักพัฒนาจึงปิดไฟล์และเอาตัวรอดไปก่อน

บททดสอบการอ่าน package.json

  • เรื่องเริ่มจากสถานการณ์ที่นักพัฒนาซึ่งใช้ JavaScript มา 10 ปีนั่งอยู่หน้าคอมพิวเตอร์ เปิดไฟล์ package.json และต้องอ่านจนจบ
  • ไฟล์นี้ไม่ใช่แค่ไฟล์ตั้งค่าธรรมดา แต่เป็นสิ่งที่ทำให้นึกถึง ความทรงจำและความเจ็บปวด ที่เคยเผชิญใน ecosystem ของ JavaScript ขึ้นมาพร้อมกัน
  • version ยังไม่ถึง 1.0 และ SemVer ยังคงเป็นความทรงจำอันไม่น่าพึงใจที่เรียนรู้มานานแล้วว่าควรละเลยอย่างไร
  • name แสดงให้เห็นสถานการณ์ที่ไม่สามารถใช้ชื่อที่ต้องการได้ เพราะมีแพ็กเกจที่ใครบางคนครอบครองไว้ตั้งแต่ 7 ปีก่อนและไม่เคยอัปเดตอีกเลย

บาดแผลเก่าของโมดูลและการ bundling

  • การมีฟิลด์ main และ browser อยู่ร่วมกันเผยให้เห็นร่องรอยของ Isomorphic JavaScript
  • ความทรงจำเกี่ยวกับการพยายาม require โมดูล fs ใน browser bundle และแฮ็กที่เคยใช้เพื่อทำให้มันทำงานได้ กลายเป็นประสบการณ์ที่ไม่น่าพึงใจ
  • type: module เชื่อมโยงกับ migration จาก require ไปสู่ import
  • ประสบการณ์การพยายาม import โมดูล CommonJS และ ESM เข้าหากันยังคงเป็นความเจ็บปวดครั้งใหญ่

ความสับสนของสคริปต์และ dependency

  • scripts คือศูนย์กลางของความสับสนที่ร้อนระอุและเจ็บปวด
    • มีรูปแบบแยกย่อยอย่าง lint, lintall, lintfast, lintdiff
    • มีการรันแบบขนาน, argument ที่ไม่ชัดเจน และการ escape ซ้ำสองครั้งสำหรับ argument รูปแบบ JSON
    • แม้จะย้ายไปใช้ yarn และ pnpm แล้ว แต่คำสั่งย่อยบางส่วนก็ยังเรียก npm อยู่
  • สคริปต์บางส่วนยังคงใช้ watchman
    • ต้องจำไว้ว่ามันไม่ควรถูกใช้ เพราะไม่รองรับ symlink
    • issue ที่เกี่ยวข้องเปิดค้างมาตั้งแต่ปี 2015
  • ยังมีสคริปต์ที่ใช้ gulp เหลืออยู่ และแม้อยากเปลี่ยนไปใช้สิ่งที่ทันสมัยกว่า แต่ก็ไม่มีใครกล้าพอที่จะเปลี่ยน

บาดแผลทางใจที่รายชื่อแพ็กเกจปลุกขึ้นมา

  • dependencies มีแพ็กเกจจำนวนมาก และแต่ละแพ็กเกจก็ปลุก ความทรงจำที่เป็นบาดแผล ของตัวเองขึ้นมา
  • left-pad เป็นแพ็กเกจเล็ก ๆ แต่ยังคงถูกจดจำในฐานะแพ็กเกจระดับตำนานที่ “ทำให้อินเทอร์เน็ตทั้งโลกพัง”
  • ทุกครั้งที่แก้รายชื่อ dependency บางแพ็กเกจจะพิมพ์คำขอบริจาคหรือคำเตือน breaking change ยาว ๆ ลงในคอนโซล
  • นักพัฒนาอยู่ในสภาพที่ได้แต่หวังว่าแพ็กเกจอันตรายจะไม่ขโมยความลับหรือทำให้คอมพิวเตอร์พัง
  • moment.js ถูกจดจำในฐานะไลบรารีที่มี API ดี แต่โลกอินเทอร์เน็ตตัดสินว่ามัน mutable เกินไป ใหญ่เกินไป และไม่รองรับ treeshaking ตอนนี้จึงอยู่ในสถานการณ์ที่ต้อง migration ไปยัง date-fns
  • เวอร์ชันแพ็กเกจล้าหลังจากมาตรฐานปัจจุบันไปมากและจำเป็นต้องอัปเกรด แต่จากประสบการณ์การอัปเกรดในอดีต จึงคาดว่าจะเกิดความเจ็บปวดอย่างหนัก
  • resolutions ยังคงเป็นความเจ็บปวดอีกแบบหนึ่งที่เลือกใช้เพื่อหลีกเลี่ยงการอัปเกรดแพ็กเกจ

ความซับซ้อนอีกชั้นที่เครื่องมือพัฒนาสร้างขึ้น

  • เมื่อดู devDependencies ก็ยากที่จะนึกถึงยุคที่ต้องการเพียง non-dev dependency
  • การตั้งค่า eslint เข้มงวดเกินไปจนความผิดพลาดเล็กน้อยก็มีขีดเส้นใต้สีแดง และ CI ปฏิบัติต่อปัญหา lint ราวกับเป็นวันสิ้นโลก
    • มันให้ความรู้สึกมั่นคงปลอม ๆ แก่วิศวกร junior ในทีม
    • เคยมีการถกเถียงหลายครั้งว่าจะเปิดกฎใดบ้าง
    • ความเจ็บปวดเพิ่มขึ้นตามจำนวน eslint-ignore ที่กระจายอยู่ทั่ว codebase
  • postcss ไม่ได้ถูกใช้โดยตรง แต่มีอยู่ในฐานะแพ็กเกจที่ dependency ของ dependency ต้องการ
    • ทุกครั้งที่พยายาม npm install บนแพลตฟอร์มใหม่ มันทำให้เกิดข้อผิดพลาดการคอมไพล์ C++ ที่ไม่ชัดเจน
  • jest เริ่มต้นในฐานะ test runner ที่รวดเร็ว แต่ตอนนี้ใหญ่และหนักขึ้น และพึ่งพาแพ็กเกจ Babel บางส่วน
    • ส่วนที่เหลือของแอปพลิเคชันถูก transpile ด้วยการผสมผสานระหว่าง esbuild และ swc
    • การตั้งค่าให้ถูกต้องสำหรับ ESM และ TypeScript นั้นยากเหมือน “โปรเจกต์วิทยาศาสตร์ระดับ PhD”
  • ใน codebase มีเครื่องมือและ parser จำนวนมากเข้ามาเกี่ยวข้อง เช่น TypeScript, esbuild, swc, babel, eslint, prettier, jest, webpack, rollup, terser
  • ใน engines มีการระบุ node ไว้ และมองว่าแม้จะย้ายไป Bun หรือ Deno ความเจ็บปวดก็จะไม่หยุด แต่จะแย่ลงกว่าเดิม
  • หลังจากอ่านจนถึงวงเล็บปีกกาปิดตัวสุดท้าย ก็ปิดแท็บ สูดหายใจตั้งสติ และเอาตัวรอดมาได้ชั่วคราวโดยที่มือและสมองยังสมบูรณ์

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

 
GN⁺ 2023-07-03
ความคิดเห็นบน Hacker News
  • ตลกดีนะ ผมเขียน JavaScript มาเกือบ 18 ปีแล้วและเลิกไปเมื่อราว 3 ปีก่อน แต่เรื่องน่าปวดหัวในลิสต์นี้ส่วนใหญ่เป็นสิ่งที่เกิดขึ้นในช่วง 10 ปีหลังนี่เอง
    ที่สะดุดตาเป็นพิเศษคือไม่มี polyfill ซึ่งถ้าเขียนในปี 2013 ยังไงก็ต้องมีแน่ ๆ แล้วฝันร้ายของ JavaScript ในปี 2013 ที่ตอนนี้แทบหายไปแล้วมีอะไรอีกบ้างนะ? แน่นอนว่ามันถูกแทนที่ด้วยลิสต์ตลกอันนี้แทน
    ช่วงที่ชอบที่สุดคือส่วนที่นับเครื่องมือและ parser ที่ใช้งานได้ในโค้ดเบส แล้วนึกถึง TypeScript, esbuild, swc, babel, eslint, prettier, jest, webpack, rollup, terser ก่อนจะเจ็บปวดจนไม่อยากรู้แล้วว่ามีอะไรตกหล่นไปอีกบ้าง

    • Grunt, Gulp, CoffeeScript, IIFE, การเขียนทับ undefined, with, การเลียนแบบ private field ด้วย closure, prototype ที่ถูกแก้ไข, global ตัวแปรตั้งต้น, this ที่เปลี่ยนไปตามตำแหน่งที่เรียก, การแปลงชนิดอัตโนมัติตอนเปรียบเทียบ…
      ใช่เลย JavaScript ผ่านอะไรแบบนี้มาเกิน 10 ปีจริง ๆ
    • เห็นด้วยเรื่อง callback แต่พอมอง JavaScript ของตัวเองเมื่อ 10 ปีก่อน ความทรมานที่ใหญ่ที่สุดคือ คลาสปลอม ที่สร้างขึ้นด้วยการแก้ SomeFunction.prototype ทั้งหมด
      แล้วก็ห่อมันด้วย anonymous function ที่รันทันทีเพื่อคืนค่าเป็น object ทำให้เรียก new SomeFunction() หรือ SomeFunction.actualFunction() ราวกับว่า SomeFunction เป็นคลาสจริง ๆ อีกเรื่องใหญ่คือยังไม่มี arrow function เลยต้องแก้ Function.prototype เองเพื่อผูก event เข้ากับ scope ด้วย .apply() หรือไม่ก็จมอยู่ในนรก .bind(this) ที่ไม่มีวันจบในทุก event callback
    • ตอนนั้นพัฒนาใน Firefox เพื่อใช้ Firebug แต่ก็ยังต้องรองรับ ie6, ie7, ie8 แยกกันทีละตัว
    • ยังมีช่วงที่เปลี่ยน header ให้เป็น Flash applet เล็ก ๆ เพื่อจะได้ใช้ฟอนต์ที่ต้องการโดยไม่ติดข้อจำกัดของฟอนต์ที่ผู้ใช้ติดตั้งไว้
    • Callback hell กับการไม่มี type โดยรวมคือเรื่องใหญ่มาก
      วันนี้ผมยังดันโชคร้ายต้องเขียนงานทดสอบให้บริษัทที่ยังใช้ JavaScript ล้วน ๆ ไม่มีทั้ง Promise หรือไฟล์ประกาศชนิดข้อมูลอยู่เลย รู้สึกเหมือนย้อนกลับไปตอนเจอ Node ครั้งแรกในปี 2012 ข้อกำหนดที่ว่าต้องใช้ JavaScript ผมพอเลี่ยงด้วย JSDoc ได้ แต่ประสบการณ์มันแย่กว่าที่จำได้มาก
  • ทุกครั้งที่เริ่มโปรเจกต์ JavaScript ใหม่ หรือพูดให้ตรงคือ โปรเจกต์ TypeScript ผมจะผ่านขั้นตอนเดิมเสมอ
    ปกติมักเป็นงานฝั่งฟรอนต์เอนด์ก็เลยเลือก React แม้จะอยากลอง Svelte ด้วยก็ตาม ตัว bundler เมื่อก่อนเคยใช้ create-react-app หรือ wrapper ของ Webpack แต่ตอนนี้ Vite ดีที่สุดเพราะตั้งค่าน้อยและรองรับเฟรมเวิร์กหลักครบ
    จากนั้นก็ติดตั้งและตั้งค่า TypeScript compiler ซึ่งส่วนใหญ่ก็อปปี้จากเทมเพลต ตั้งเป้าเป็น JavaScript เสถียรล่าสุดและโมดูล ESM แล้วจัด eslint กับ prettier ให้เข้ากัน พร้อมเพิ่มปลั๊กอินอย่าง TypeScript และ React ใส่ hook ให้รัน Prettier กับ eslint ก่อน commit ด้วย
    ยังต้องติดตั้งส่วนขยาย IDE และทำ .devcontainer หรือรายการส่วนขยายที่แนะนำไว้อีก ผมไม่ค่อยสนใจสไตล์เท่าไร แต่ให้ความสำคัญกับความสม่ำเสมอของโค้ดและการจับความผิดพลาด ดังนั้น eslint ก็มักใช้ชุดคอนฟิกสำเร็จรูป
    จากนั้นก็ตั้งค่า unit test อย่าง jest หรือ vitest แล้วค่าตั้งที่เกี่ยวกับ TypeScript กับกฎ eslint ก็พ่วงตามมาอีก ส่วน CSS framework ผมชอบ tailwind เลยยังติดตั้ง styled-components กับ twin.macro เพื่อให้เข้ากับ React ได้ดี รวมถึงปลั๊กอิน Google Fonts หรือไลบรารีฟอนต์ด้วย
    ผ่านไปประมาณหนึ่งวันถึงจะเริ่มเขียนโปรแกรมได้ ทำไมมันต้องมีงานเยอะขนาดนี้นะ? ทั้งที่มีคนใช้ชุด Vite + TypeScript + React/Vue/Svelte + eslint/prettier + tailwind/bootstrap + jest/vitest กันเยอะมาก ทำไมถึงไม่มี ไลบรารีแบบไม่ต้องตั้งค่า ที่พร้อมใช้กับ 90% ของกรณีใช้งานกัน?

    • ต่อให้เป็นคนที่รู้ทั้งหมดนี้อยู่แล้วก็ยังใช้เวลาหนึ่งวัน ในฐานะคนทำฝั่งแบ็กเอนด์และระบบปฏิบัติการ ผมพยายามเข้าไปทำสแตกแบบนี้อยู่หลายครั้ง แต่พูดตรง ๆ ว่าหลายครั้งก็ล้มเหลวเฉย ๆ
      ต่อให้พอทำให้ toolchain รันขึ้นมาได้ ก็ไม่เคยรู้สึกว่าตัวเองควบคุมมันได้เลย เหมือนแค่สั่นนิดเดียวทุกอย่างก็จะพัง และก็ดูเหมือนจะซ่อมเองไม่ได้ด้วย
      ช่วงหลังผมเลยมองสแตก JavaScript ส่วนใหญ่นี้ว่าเป็น อุปสรรค ต่อสิ่งที่ผมอยากทำ แล้วกลับไปสร้างแอปแบบ server-side rendering ด้วย Flask และ Jinja2 เหมือนสมัยก่อน มันไม่ได้ล้ำหรือดูแวววาว และตอนนี้ก็ยังค่อนข้างน่าเกลียดเพราะไม่มี CSS แต่ก็มีคนแนะนำให้ลองใช้ CSS สมัยใหม่ล้วน ๆ ดู ถึงอย่างนั้นก็ยังน่าทึ่งว่าทำฟีเจอร์ได้เร็วแค่ไหนบนสแตกนั้น
    • มี linter ตั้งสองตัว แค่นี้ก็เพี้ยนพอแล้ว อย่างอื่นหนักกว่านี้อีก แต่แม้แต่ชิ้นส่วนเล็กที่สุดของการเลือกเครื่องมือใน ecosystem ของ JavaScript ก็ยังเต็มไปด้วย ความทรมาน
    • ผมก็แค่คัดลอก TypeScript starter directory แล้วเปลี่ยนชื่อใน package.json เท่านั้นเอง แน่นอนว่าผมทำแต่แบ็กเอนด์ แต่สำหรับฟรอนต์เอนด์ก็น่าจะทำ เทมเพลตส่วนตัว แบบนั้นได้เหมือนกันไม่ใช่เหรอ?
    • npm create ไม่ช่วยทำให้เหรอ?
      ถ้าสั่ง npm create vue ก็จะได้ชุด Vue ที่ค่อนข้างดี ใช้งานได้จริง และตั้งค่าส่วนใหญ่ไว้ให้แล้ว ผมเห็นด้วยว่ามีทั้ง boilerplate และของจุกจิกเยอะ แต่แอปที่เราสร้างบนเว็บทุกวันนี้ก็ใหญ่กว่าเมื่อก่อนมากเหมือนกัน จะใช้ JavaScript ผ่าน ESModules แบบไม่พึ่งเครื่องมือเลยก็ได้ แต่คนไม่ค่อยทำกันเพราะเครื่องมือเหล่านั้นมันช่วยทำอะไรบางอย่างได้จริง อาจไม่ใช่วิธีที่สะอาดที่สุด แต่ยังไงมันก็ใช้ได้
    • น่าจะสร้าง stub project ที่ใส่ชุดคอนฟิกที่ชอบทั้งหมดไว้ แล้วอัปขึ้น GitHub
      เวลาเริ่มโปรเจกต์ใหม่ก็แค่ clone มาแล้วเปลี่ยนชื่อไม่กี่จุดก็น่าจะพร้อมใช้งาน
  • นี่เป็นอีกกรณีที่คนพูดว่า JavaScript แต่จริง ๆ หมายถึง “สารพัดของจุกจิกใน ecosystem ของ Node”
    เปิดมาก็บอกว่าต้องเปิดอ่านไฟล์ package.json แล้วหลังจากนั้นก็ยังวนอยู่กับเรื่องนั้นต่อไป แทบไม่มีอะไรที่เกี่ยวกับตัว JavaScript เองในสิ่งที่ยกมาพูด

    • นักพัฒนา JavaScript ที่ไม่ใช้ NodeJS มีสัดส่วนเท่าไรกัน?
      จริงอยู่ว่า JavaScript กับ NodeJS ไม่ใช่สิ่งเดียวกัน แต่คนส่วนใหญ่ก็คงเข้าใจว่าผู้เขียนหมายถึงอะไร ถ้าเขียนให้แม่นกว่านี้ก็คงดีกว่า แต่จะบอกว่าผิดไปเลยก็คงไม่ถึงขนาดนั้น
    • ใช่ งั้นก็แปลว่า ecosystem ไม่ใช่เป้าหมายที่ใช้วิจารณ์ตัวภาษาได้อย่างมีเหตุผลสินะ
    • ลองเขียน JavaScript แบบจริงจังโดยไม่ใช้ bundler ที่ใช้ package.json ดูสิ จนกว่า ECMA จะใส่ package manager หรือ bundler เข้าไปในสเปกอย่างเป็นทางการ package.json ก็ถือเป็น ส่วนหนึ่งของ JavaScript โดยพฤตินัย
    • ถ้ามันทำให้หงุดหงิดขนาดนั้น เวลามีใครพูดว่า JavaScript ก็คิดไปเลยว่าเขาหมายถึง ECMAscript
    • ใช่ นี่เป็นคำวิจารณ์ต่อ ecosystem ของ JavaScript
  • ชอบโทนล้อเล่นแบบนี้ดี หลังจากผิวหนังกับปลายประสาทถูกเผาไหม้ไปหลายชั้นแล้ว การย้อนนึกถึงจุดเจ็บพวกนี้ก็มีประโยชน์อยู่
    อีกมุมหนึ่งก็คือ คุณสามารถยื่น MacBook ใหม่ให้ junior developer ที่มีไฟ แล้วโยนลงน้ำลึกได้เลย เขาก็ยังทำงานได้ภายในวันเดียว ไม่ต้องรู้เรื่อง container, .NET, nginx หรือเครื่องมือ command line ที่ใช้บ่อยอีกเป็นร้อยตัว และถ้ามีปัญหาก็แค่ค้นหาเอา

    • ใช่ ที่ย้อนแย้งคือเพราะการประนีประนอมแบบนั้น ต่อให้โยน senior developer ที่ทำของให้รันในเบราว์เซอร์มา 20 ปีลงไป เขาก็อาจยังไม่พร้อมภายในวันเดียว
      ทั้งที่รู้ว่าถ้าได้จับต้องเองจริง ๆ ก็สร้างเรือทั้งลำได้ในไม่กี่วัน แต่กลับต้องมาซ่อมเรือในขวดด้วยเครื่องมือหยาบ ๆ ที่มีให้ พร้อมต่อสู้กับชั้นของความซับซ้อนที่ไม่จำเป็น ความรู้สึกนี้แหละเวลาทำโปรเจกต์ส่วนตัวด้วย JavaScript, HTML, CSS ล้วน ๆ ได้อย่างคล่อง แล้วถูกโยนเข้าไปทำงานฟรอนต์เอนด์สมัยใหม่
    • แล้วจากนั้นก็เอาอะไรบางอย่างมายำติดกันอยู่ 1 ถึง 3 วัน เสร็จแล้วเสียใจไปอีก 10 ปี ก่อนจะมาเขียนบทความแบบนี้ วัฏจักร ดำเนินต่อไป
    • junior ที่ฉันรู้จักจะพูดว่า “งั้นเรามาสร้าง framework เพื่อจัดการความซับซ้อนนี้กัน”
      แล้วก็ไร้เดียงสาว่าการสร้างมันใช้เวลาหลายเดือน ทั้งที่ปัญหาส่วนหนึ่งก็คือ framework มีมากเกินไป และพอถึงวันถัดไปมันก็อาจล้าสมัยแล้ว
    • ตอนนี้ไม่ค้นหาแล้ว แต่ไปถาม ChatGPT แทน
  • “ฉันทำตามคำอธิบายแล้วมันบอกว่าไม่ได้ติดตั้ง grunt ตอนนั้นฉันก็เป็นคนแก่แล้ว เลยไม่ค่อยรู้ว่า grunt คืออะไร แล้วไฟล์ grunt ของฉันก็ดูเหมือนจะมีอะไรไม่ถูกต้อง ก็เลยไปค้นมาหน่อยจนพอรู้ว่า grunt คืออะไร Grunt คือ… จริง ๆ แล้วฉันก็ยังไม่ค่อยรู้ว่ามันคืออะไรอยู่ดี”
    --Joe Armstrong, https://www.youtube.com/watch?v=lKXe3HUG2l4
    เมื่อไม่กี่วันก่อนฉันรัน gem install wayback_machine_downloader ฉันไม่เคยชอบภาษา Ruby มากพอจะเข้าไปคลุกใน ecosystem ของมัน แต่จากคนนอกมองเข้าไป ecosystem นี้ดูคงเส้นคงวาอย่างน่าทึ่ง gem ก็ยังเป็นเครื่องมือที่ยังใช้อยู่ และ Rails ก็ยังอยู่เหมือนเดิม
    ฉันกำลังรอโปรเจกต์ใหม่ที่ต้องใช้ฟรอนต์เอนด์ซับซ้อนพอจะเกิน JavaScript 0~30 บรรทัด ตอนนั้นแทนที่จะใช้ framework ยักษ์ที่กำลังฮิตที่สุดในยุคนี้ ฉันน่าจะมีความสุขกว่าถ้าใช้ HTMX

  • นี่ไม่ใช่บทความเกี่ยวกับ JavaScript แต่เป็นเรื่องของ npm
    ฉันเกลียด npm เพราะสารพัดเรื่องจุกจิกแบบนี้ และพยายามหลีกเลี่ยงมันให้มากที่สุด ส่วนตัวฉันใช้ Deno และที่ทำงานก็ใช้ของคล้าย bazel บน monorepo ที่ช่วยให้ไม่ต้องพึ่ง npm
    แต่ฉันรู้สึกว่า JavaScript/TypeScript เป็นภาษาที่เขียนโปรแกรมได้สนุก และเป็นภาษาที่หยิบมาใช้เป็นอันดับแรกไม่ว่าจะสร้างอะไร มันน่าเศร้าที่เวลาคนพูดว่า “JavaScript ห่วย” เขามักหมายถึงการ build แอป React ด้วย npm มันห่วยต่างหาก การเขียนโค้ด JavaScript/TypeScript สมัยใหม่นั้นสนุกจริง ๆ

    • เห็นด้วย ฉันกำลังทำวิดีโอเกมอยู่ แล้วพอตัดสินใจว่าจะไม่ใช้ dependency เลย การเขียนโค้ดก็สนุกขึ้นมากจริง ๆ
  • รู้สึกว่า JavaScript กับ ecosystem ของมันได้ทิ้ง PTSD ไว้ให้พวกเราทุกคน จนทำให้สนุกกับความตลกของบทความนี้ไม่ได้
    มีการถกกันแบบ “จริงจัง” มากเกินไปกับบทความขำ ๆ แบบนี้ จะชำแหละกันเต็มที่ก็ได้ แต่ก็น่าจะจำไว้ว่าความตั้งใจที่แท้จริงคืออารมณ์ขัน

    • เป็นเรื่องตลกไม่ได้แปลว่าไม่จริงจัง
  • พูดตรง ๆ ก็คือ ecosystem แรกที่ฉันเริ่มต้นคือ Node และสิ่งอื่นที่ไปเรียนรู้ทีหลังก็ล้วนมีปัญหาบ้าบอของตัวเองมากพอ ๆ กัน
    Haskell ใช้งานข้ามหลายเครื่องได้ยากมาก การติดตั้งบน MacOS ในปี 2019 ก็ทรมาน และการจัดการ ecosystem ก็ลำบาก macro กับ extension ก็ชวนสับสนมาก และความเข้ากันได้ย้อนหลังของภาษาก็ไม่ได้ดีนัก ในทางกลับกัน JavaScript ปี 2010 โดยทั่วไปยังคาดหวังได้ว่าจะรันได้เหมือนเดิมในปี 2023
    แม้แต่การทำ Docker image หรือ environment อย่าง codespace/gitpod ให้ดีจริง ๆ ก็ยังยาก และ image พื้นฐานที่ GitHub ให้มาก็ไม่ค่อยดีและมีปัญหา
    C นั้นโดยมากก็พอใช้ได้บนแทบทุกแพลตฟอร์ม แต่ตัวภาษาเองก็ซับซ้อนเอาเรื่อง และต้องอาศัยความรู้มหาศาลเกี่ยวกับระบบโดยรวม ผลคือมันทำให้ได้โค้ดที่พกพาได้น้อยและไม่เหมาะกับงานเขียนโปรแกรมทั่วไปส่วนใหญ่ได้ง่าย
    จะพูดต่อก็ยังได้ แต่ใครที่เคยใช้หลายภาษามาบ้างก็คงรู้ว่า ecosystem ทุกแห่งล้วนมีข้อบกพร่องหลายอย่าง และเราทุกคนก็ยังต้องทนทุกข์กันต่อไป ฉันไม่เคยเซ็ตอัปโปรเจกต์ PHP เสร็จภายในไม่กี่วันเลย ส่วน Elm แม้จะเจ็บปวดน้อยกว่า แต่ก็มีปัญหาเฉพาะตัวเรื่องสถานะแบบ benevolent dictator กับความเร็วในการพัฒนา

    • เพราะงั้นฉันเลยพยายามใช้ Go กับแทบทุกอย่าง ถึงจะไม่ใช่ตัวเลือกที่ดีที่สุดเสมอไป แต่งานจุกจิกน้อยสุด
    • C ซับซ้อนเหรอ? ไม่ว่าฉันจะใช้มันบ่อยแค่ไหน มันก็แทบเป็นภาษาเดียวที่เก็บไว้ในหัวได้หมด ไวยากรณ์ JavaScript สมัยใหม่บางส่วนฉันใช้ทุกวันยังลืมง่ายมาก
  • เป็นนักพัฒนาหลายภาษาที่คิดว่าตัวเองถนัดทั้งหลายกระบวนทัศน์การเขียนโปรแกรม หลายภาษา รวมถึงทั้งฝั่งฟรอนต์เอนด์และแบ็กเอนด์
    ทุกครั้งที่เห็น package.json ยาวเกิน 20 บรรทัด ก็แทบจะตอบสนองแบบนี้อย่างแม่นยำ

    • ตอนนี้กำลังจ้อง Angular ฟรอนต์เอนด์ตัวใหม่ที่กำลังพัฒนาอยู่ โดยมีคอมโพเนนต์ฝั่งฟรอนต์เอนด์ 4 ตัว และแต่ละตัวมี package.json ยาวเกิน 200 บรรทัด
      พูดออกเสียงราวกับพยายามขับไล่ปีศาจว่า “อย่าหวาดกลัว ความกลัวคือสิ่งที่สังหารจิตใจ ความกลัวคือความตายเล็ก ๆ ที่นำมาซึ่งการสูญสิ้นโดยสมบูรณ์ ข้าจะเผชิญหน้ากับความกลัวของตนเอง ข้าจะยอมให้มันผ่านเข้ามาและผ่านพ้นไป และเมื่อมันผ่านไปแล้ว ข้าจะใช้ดวงตาแห่งจิตมองดูเส้นทางของมัน ตรงที่ความกลัวผ่านไปจะไม่เหลือสิ่งใด มีเพียงข้าเท่านั้นที่ยังคงอยู่”
      กำลังร้องไห้อยู่
    • ฉันก็เหมือนกัน แต่ขอพูดนอกเรื่องนิดหนึ่ง ลิงก์ในโปรไฟล์ถูก uBlock Origin บล็อกและพาไปสู่โพรงกระต่ายของเว็บไซต์แปลก ๆ ไม่เคยใช้ hackernewsers เลยไม่รู้ว่านี่เป็นการทำงานปกติหรือเปล่า
  • ฉากที่นักพัฒนา JavaScript สายเก่าอ่านบทความนี้พร้อมทุกข์ทรมานจาก PTSD และภาพย้อนอดีต
    อย่าหวาดกลัว ความกลัวคือสิ่งที่สังหารจิตใจ ความกลัวคือความตายเล็ก ๆ ที่นำมาซึ่งการสูญสิ้นโดยสมบูรณ์
    ข้าจะเผชิญหน้ากับความกลัวของตนเอง ข้าจะยอมให้มันผ่านเข้ามาและผ่านพ้นไป และเมื่อมันผ่านไปแล้ว ข้าจะใช้ดวงตาแห่งจิตมองดูเส้นทางของมัน
    ตรงที่ความกลัวผ่านไปจะไม่เหลือสิ่งใด มีเพียงข้าเท่านั้นที่ยังคงอยู่
    อ่านบทความจนจบและตระหนักว่าตัวเองรอดมาได้ แต่ก็ชุ่มไปด้วยเหงื่อเสียแล้ว