2 คะแนน โดย GN⁺ 2024-04-27 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • Bun v1.1.5 เพิ่มตัวรายงานแครช bun.report ที่ส่งข้อมูลสแตกของ Zig/C++ ผ่าน URL ขนาดราว 150 ไบต์ที่ไม่มีข้อมูลส่วนตัว แม้จะเกิดแครชหรือแพนิก
  • ตัวรายงานแครชของ OS แบบเดิมและคอร์ดัมป์มีภาระด้าน debug symbols, ประสิทธิภาพ, ความเป็นส่วนตัว, ขนาดไฟล์รันได้ สูง จึงนำมาใช้กับเครื่องมือ CLI อย่าง Bun ได้ยาก
  • วิธีใหม่นี้จะแปลงแอดเดรสที่ความหมายไม่ชัดเจนเพราะ ASLR ให้เป็น แอดเดรสสัมพัทธ์อิงตามโมดูล แล้วให้เซิร์ฟเวอร์กู้คืนชื่อฟังก์ชันด้วย debug symbols ที่ตรงกับ commit SHA และแพลตฟอร์ม
  • ใน URL จะมีแพลตฟอร์ม ซับคอมมานด์ commit SHA ฟีเจอร์แฟลก แอดเดรสสแตก ประเภทแครช และข้อความแครช โดยแอดเดรสสแตกจะถูกเข้ารหัสให้สั้นด้วย base64 VLQ
  • จะไม่มีการส่งซอร์สโค้ด JavaScript/TypeScript หรือ environment variables แต่ส่งเฉพาะ ข้อมูลสแตกของ Zig/C++ และเมทาดาทาบางส่วน ที่ทีม Bun ต้องใช้ในการวิเคราะห์

เหตุผลที่ Bun สร้างตัวรายงานแครชของตัวเอง

  • ณ เวลาที่เขียน Bun มี GitHub issues ที่ยังเปิดอยู่มากกว่า 2,600 รายการ และบาง issue ก็ยากเป็นพิเศษทั้งในการทำซ้ำและดีบัก
  • บริการรายงานแครชอย่าง Sentry เหมาะกับแอปและผลิตภัณฑ์ SaaS แต่ถ้าให้อัปโหลดคอร์ดัมป์จากเครื่องมือ CLI อย่าง Bun จะเกิดปัญหาเรื่องความเป็นส่วนตัว ประสิทธิภาพ และขนาดไฟล์รันได้มากขึ้น
  • Bun v1.1.5 จึงนำเสนอ ฟอร์แมตใหม่ขนาดเล็ก สำหรับรายงานแครชของ Zig และ C++
    • รายงานแครชเก็บอยู่ใน URL ขนาดประมาณ 150 ไบต์
    • ไม่มีข้อมูลส่วนตัวรวมอยู่ด้วย

ข้อจำกัดของการใช้ตัวรายงานแครชของ OS เพียงอย่างเดียว

  • ระบบปฏิบัติการบางตัวอย่าง macOS มีตัวรายงานแครชในตัว แต่ถ้าจะใช้งานได้อย่างเหมาะสม โดยทั่วไปต้องแจกจ่าย debug symbols ไปพร้อมกับแอปพลิเคชัน
  • debug symbols ทำให้ขนาดไฟล์แจกจ่ายของ Bun เพิ่มขึ้นมาก
    • debug symbols บน Linux มีขนาดประมาณ 30MB
    • debug symbols บน macOS มีขนาดประมาณ 9MB
    • ไฟล์ .pdb บน Windows มีขนาด มากกว่า 250MB
  • ตัวอย่างไฟล์รันได้ของ Bun ลดจาก 60M เหลือ 51M หลังใช้ llvm-strip
  • หากเกิดแครชโดยไม่มี debug symbols สแตกเทรซจะเหลือเพียง ??? กับแอดเดรส ทำให้ใช้งานได้ไม่มาก
  • เนื่องจาก ASLR(Address space layout randomization) แอดเดรสของฟังก์ชันจะมีออฟเซ็ตแบบสุ่มปะปนอยู่ จึงไม่สามารถกู้คืนชื่อฟังก์ชันได้โดยตรง

วิธีทำงานของ bun.report

  • เมื่อเกิดแครชหรือแพนิกใน Bun v1.1.5, Bun จะพิมพ์ลิงก์ bun.report ออกมาพร้อมเวอร์ชัน แพลตฟอร์ม อาร์กิวเมนต์ที่ใช้รัน การใช้หน่วยความจำ และข้อความแครช
  • เมื่อผู้ใช้เปิดลิงก์ จะถูกรีไดเร็กต์ไปยัง ฟอร์ม issue ของ GitHub ที่กรอกไว้ล่วงหน้า
  • ภายใน URL มีการเข้ารหัสสแตกเทรซที่ถูกรีแมปแล้วไว้
  • เซิร์ฟเวอร์จะกู้คืนแอดเดรสสแตกจากข้อมูลใน URL และแปลงให้เป็นรายงานแครชที่ทีม Bun อ่านได้

ขั้นตอนการแปลงแอดเดรสให้เป็นสแตกเทรซที่อ่านได้

  • แอดเดรสของฟังก์ชันคือพอยน์เตอร์ที่ชี้ไปยังตำแหน่งที่โค้ดของแอปพลิเคชันถูกโหลดเข้าไปในหน่วยความจำ และมีออฟเซ็ตแบบสุ่มเพื่อความปลอดภัยรวมอยู่
  • แนวคิดพื้นฐานคือ นำ base address ของไบนารีมาลบออกจากแอดเดรสดิบเพื่อให้ได้แอดเดรสสัมพัทธ์
  • การติดตั้งจริงซับซ้อนกว่านั้นเพราะ API ของแต่ละแพลตฟอร์มต่างกัน
    • Windows ใช้แฟลก GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS กับ GetModuleHandleExW แล้วใช้พอยน์เตอร์ของโมดูลเป็น base address
    • Linux ใช้ dl_iterate_phdr วนดูโมดูลที่ถูกโหลด และใช้ dl_phdr_info.dlpi_addr ของโมดูลที่มีแอดเดรสนั้นเป็น base address
    • macOS ใช้ _dyld_image_count, _dyld_get_image_header เพื่อวนดูโมดูล และใช้ _dyld_get_image_vmaddr_slide เพื่อดึง ASLR slide
      • แอดเดรสผลลัพธ์บน macOS จะยังมี image offset ติดอยู่ ซึ่งสำหรับ Bun คือ 0x100000000
      • เพื่อให้ URL สั้นลง จะตัดออฟเซ็ตนี้ออก แต่ต้องบวกกลับเข้าไปก่อนรีแมปด้วย llvm-symbolizer
  • บน Linux และ macOS โมดูลตัวแรกจะชี้ไปยังไบนารีหลักของแอปพลิเคชัน
  • บน Windows สามารถตรวจได้ว่าเป็นไบนารีหลักหรือไม่โดยเทียบชื่อโมดูลกับ peb.ProcessParameters.ImagePathName
  • Bun ไม่ดาวน์โหลดและพาร์ส debug symbols บนเครื่อง แต่ มอบหมายการ demangle ให้เซิร์ฟเวอร์
    • เซิร์ฟเวอร์สามารถแคช debug symbols ได้
    • สามารถ demangle สแตกเทรซได้ภายในไม่กี่วินาที
    • และทำหน้าที่เป็นลิงก์สำหรับเปิด GitHub issue ใหม่ไปพร้อมกัน

โครงสร้าง URL ของ bun.report

  • URL ของ bun.report เข้ารหัสข้อมูลต่อไปนี้ไว้
    • Platform: อักขระหนึ่งตัวที่บอกแพลตฟอร์ม เช่น w คือ x86_64 Windows และ M คือ aarch64 macOS
    • Subcommand: อักขระหนึ่งตัวที่บอกซับคอมมานด์ เช่น bun test, bun install, bun run
    • Commit SHA: commit SHA ของ Bun เวอร์ชันปัจจุบัน ใช้สำหรับดึง debug symbols ภายหลัง
    • Feature Flags: ตัวบ่งชี้ API และฟีเจอร์ที่ถูกใช้ก่อนเกิดแครช
    • Stack Trace Addresses: แอดเดรสที่คำนวณได้จากขั้นตอนก่อนหน้า
    • Crash Type: อักขระหนึ่งตัวที่บอกประเภทของแครช
    • Crash Message: ข้อความที่มีรูปแบบต่างกันตามประเภทแครช
  • หมายเลขเวอร์ชันใน URL มีไว้ให้มนุษย์อ่านเป็นหลัก มากกว่าจะใช้ในการประมวลผลจริง
  • ข้อมูลเท่านี้ก็ช่วยให้พอมองลักษณะของแครชบางส่วนได้ด้วยตาเปล่า
    • หากเห็นตัวระบุ w ก็รู้ได้เร็วว่าเป็นแครชบน Windows
    • หากเห็น A2 ตอนท้ายสตริง ก็ระบุได้ว่าเป็น segmentation fault

การเข้ารหัส VLQ เพื่อให้ URL สั้น

  • แอดเดรสในสแตกเทรซถูกเข้ารหัสเป็นตัวเลขแบบ base64 Variable Length Quantity(VLQ) เพื่อให้ URL สั้น
  • VLQ ทำให้ตัวเลขขนาดเล็กใช้ตัวอักษรน้อยลง แต่ก็ยังเข้ารหัสตัวเลขขนาดใหญ่ได้
  • เทคนิคเดียวกันนี้ถูกใช้ใน JavaScript source maps เพื่อเก็บหมายเลขบรรทัด
  • เซิร์ฟเวอร์จะถอดรหัสค่า VLQ กลับมาเป็นแอดเดรสสัมพัทธ์ แล้วใช้ commit hash และแพลตฟอร์มเพื่อดาวน์โหลด debug symbols ก่อน demangle ชื่อฟังก์ชันด้วย llvm-symbolizer
  • ในตัวอย่างแครชพบว่า assertion ล้มเหลวใน dirInfoCachedMaybeLog ซึ่งเป็นส่วนหนึ่งของโค้ด module resolver บน Windows

การเข้ารหัสฟีเจอร์แฟลก

  • URL ยังเข้ารหัส จำนวนเต็ม 64 บิต ด้วย โดยแต่ละบิตสอดคล้องกับการใช้งานฟีเจอร์เฉพาะของ Bun
  • แฟลกนี้ให้เบาะแสว่า API และระบบใดอาจมีส่วนต่อการเกิดแครช
    • หากมีการโหลดไฟล์ .env อัตโนมัติ จะตั้งค่าฟีเจอร์ dotenv
    • หากใช้ fetch() จะตั้งค่าฟีเจอร์ fetch
  • Bun ติดตามการใช้ฟีเจอร์ผ่านคอนเทนเนอร์ตัวแปรโกลบอล และภายในแต่ละ API จะเพิ่มค่าตัวเลขที่เกี่ยวข้องเพื่อระบุว่าได้ใช้งานแล้ว
  • ใช้เมตาโปรแกรมมิงแบบ compile time ของ Zig เพื่อวนผ่านรายการฟีเจอร์และสร้าง packed struct แบบไดนามิกที่ใช้ 1 บิตต่อฟีเจอร์
  • การใช้ inline for ทำให้สามารถวนผ่านรายการฟีเจอร์ในช่วง compile time แต่ตั้งค่าบิตจริงในช่วง runtime ได้
  • หากเพิ่มฟีเจอร์ใหม่เข้าไปใน Features struct เดิม ตัวรายงานแครชก็จะรองรับได้โดยไม่ต้องเขียนซ้ำ
  • วิธีเดียวกันนี้ทำได้ด้วยแมโครใน C หรือ Rust เช่นกัน แต่ในการติดตั้งของ Bun นั้น Zig comptime ทำให้โค้ดเรียบง่ายและอ่านง่ายกว่า

ความต่างจากคอร์ดัมป์

  • คอร์ดัมป์มีข้อมูลมากกว่ามาก แต่ก็มีขนาดใหญ่ ต้องมี debug symbols จึงจะมีประโยชน์ และอาจมีข้อมูลอ่อนไหวหรือข้อมูลลับรวมอยู่จำนวนมาก
  • วิธีรายงานแบบใหม่ของ Bun หลีกเลี่ยงการส่งซอร์สโค้ด JavaScript/TypeScript, environment variables และข้อมูลอ่อนไหวอื่น ๆ
  • แทนที่จะส่งทุกอย่างไปโดยปริยาย จะส่งเฉพาะ สแตกเทรซของ Zig/C++ และรายละเอียดบางอย่างที่มีแนวโน้มจำเป็นต่อการวิเคราะห์ปัญหา
  • หากต้องการข้อมูลเพิ่ม ก็สามารถขอจากผู้ใช้แยกต่างหากได้
  • ทำให้ทีม Bun วินิจฉัยแครชได้ง่ายกว่าสถานการณ์แบบเดิมที่เหลือเพียงแอดเดรสที่ยังไม่ถูกแมป

เดโม

  • มีเว็บแอปขนาดเล็กสำหรับทดสอบตัวรายงานแครชที่ bun.report
  • หากเติม /view ต่อท้าย URL ของรายงานแครชใด ๆ ก็จะเปิดหน้าเว็บแอปนี้ได้

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

 
GN⁺ 2024-04-27
ความคิดเห็นบน Hacker News
  • ถ้าเหตุผลที่ใช้วิธีนี้แทน stack trace แบบทั่วไปคือเพื่อหลีกเลี่ยงการแจกจ่าย debug symbols ขนาดหลาย MB ก็ดูเหมือนว่าพวกเขาจะมองข้ามทางเลือกที่ดีกว่าอย่างการใส่เฉพาะชื่อฟังก์ชันไว้ใน debug table
    เป็นวิธีที่ดีกว่ามากเมื่อเทียบกับการต้องใช้เว็บเซอร์วิสเพื่อดู stack trace และนี่ไม่ใช่แค่ทฤษฎี แต่มีการ implement ไว้แล้วใน LLVM: https://clang.llvm.org/docs/UsersManual.html#cmdoption-gline...

    • เหตุผลหลักที่ใช้วิธีนี้แทน stack trace แบบทั่วไปไม่ใช่เพราะขนาดของ debug symbols แต่เพราะแทบไม่มีใครอดทนพอจะโพสต์ crash report ลง GitHub issue
      ถ้าใช้ URL เดียวแล้วช่วยกรอกสิ่งที่จำเป็นให้เกือบอัตโนมัติ มันก็ง่ายพอ และนั่นแหละที่จะทำให้นักพัฒนาโพสต์ crash report จริง ๆ ขนาดก็สำคัญ เพื่อไม่ให้เกิดข้อเสียกับผู้ใช้ แต่ประเด็นหลักคือทำให้ทั้งกระบวนการง่ายมาก ๆ
    • คำว่า “มองข้ามทางเลือกที่ดีกว่า” และ “ดีกว่าแน่นอน” ฟังดูตัดสินไปหน่อย น่าจะเป็นไปได้ว่าพวกเขารู้ถึงความเป็นไปได้นั้นอยู่แล้ว
      ใน use case นี้ การต้องดู stack trace ผ่านเว็บเซอร์วิสไม่ใช่ข้อเสียใหญ่ คล้ายกับการ obfuscate/minify บันเดิล JavaScript ฝั่ง frontend แล้วอัปโหลด source map ไปยัง Sentry จากนั้นจึงกู้คืน stack trace ที่มาจากเบราว์เซอร์ของผู้ใช้ผ่าน Sentry ผู้ใช้ก็ไม่ได้จะดู stack trace นั้นอยู่แล้ว และผมก็ไม่ได้รู้สึกไม่สะดวกที่ต้องใช้ Sentry ดู เพราะถ้าไม่ทำแบบนั้นก็คงไม่ได้เห็นมันเลย
    • ถ้าวิจารณ์ว่า “แน่นอนว่า” หรือ “แค่” ทำอย่างอื่นก็พอ ทั้งที่ไม่รู้บริบทของการถกเถียงและไม่รู้ว่ามี trade-off อะไรบ้าง มันฟังดูหยิ่งไปหน่อย
      การเสนอทางเลือกทำได้หลายแบบ
    • บน macOS/iOS ยังมีวิธีแจกจ่ายโดยใส่เฉพาะเซกชัน LC_FUNCTION_STARTS ใน Mach-O binary ได้ด้วย
      บนแพลตฟอร์มเหล่านี้ นี่คือวิธีที่ symbolication ค้นหาชื่อฟังก์ชันของ system libraries ได้โดยไม่ต้องมี debug symbols แบบเต็ม
    • ถึงอย่างนั้นก็ยังอาจใหญ่พอสมควร ส่วนตัวผมเห็นว่าคุ้มค่า เลยมักใส่ไว้เสมอ แต่ซอฟต์แวร์ส่วนใหญ่ไม่ได้ทำแบบนั้น
  • ยอดเยี่ยมและสร้างสรรค์มาก อยากให้หลายโปรเจกต์ทำตามวิธีนี้ แก่นของมันคือการบันทึก stack trace ด้วย relative program counter อ้างอิงตาม executable/shared object
    เท่าที่รู้ Bun ถูกลิงก์แบบ static แต่ถ้าเป็นระบบลิงก์แบบ dynamic ก็น่าจะต้องใส่ shared object ID เป็นเลขขนาดเล็กนำหน้า program counter ที่ normalize แล้วแต่ละตัว

    • ไม่ใช่วิธีใหม่ทั้งหมด ในสภาพแวดล้อมอย่างเกมที่ ไม่สามารถแจกจ่าย symbols ได้ มักใช้กันเมื่อเกิด crash บนพีซีของผู้เล่น
      ตัวอย่างเช่น Unreal Engine crash reporter ส่งรูปแบบเรียบง่ายแบบนี้ได้มาหลายปีแล้ว และสามารถกู้คืนฟังก์ชัน/หมายเลขบรรทัดของแต่ละ stack frame ได้ค่อนข้างแม่นยำ แต่โดยทั่วไปยังนิยม minidump มากกว่า เพราะถ้ามี stack variables ด้วยก็มักได้เบาะแสเพิ่มเติมว่าเกิดอะไรขึ้น
  • Microsoft ทำเรื่องแบบนี้ได้ดีจริง ๆ ใน SQL Server ใช้ minidump ที่ลบข้อมูลส่วนบุคคลออกแล้ว ซึ่งเล็กมากและมีประโยชน์มาก
    แม้ในตอนนั้น ซึ่งก็คือ 15 ปีก่อน full dump ของ SQL Server ใน production ก็เป็นไฟล์ขนาดมหึมาจนเคลื่อนย้ายลำบากแล้ว

    • สงสัยว่าเป็นสำหรับบริการภายในของ Microsoft หรือสำหรับสภาพแวดล้อมที่ส่งให้ลูกค้าใช้ ถ้าเป็นอย่างหลัง พวกเขารู้ได้อย่างไรว่าอะไรคือ ข้อมูลที่ระบุตัวบุคคลได้?
  • ผมติดตาม Bun มาหลายปีตั้งแต่เห็นทวีตแรกเกี่ยวกับ Zig และเพิ่งเริ่มใช้เมื่อไม่นานนี้ มันก็แค่ทำงานได้ดีโดยไม่ต้องวุ่นวายอะไรเป็นพิเศษ

  • Bun ค่อนข้างน่าสนใจ ผมลองใช้กับโปรเจกต์ตัวอย่างเล็ก ๆ ไม่กี่อันแล้ว ความเร็วดี และชอบที่รวม package management กับ JavaScript runtime ไว้ด้วยกัน
    แต่ในโปรเจกต์จริงจังส่วนใหญ่ผมใช้ Dependabot อยู่ เท่าที่รู้ การรองรับ Bun ของ Dependabot กำลังอยู่ระหว่างทำ หรืออย่างน้อยก็มีการพูดคุยกันในบาง issue ของ repository ดังนั้นผมจึงชะลอการใช้ไว้จนกว่าการรองรับจะถูกปล่อยออกมา

    • พวกเราก็ลังเลก่อนย้ายเพราะ ยังไม่รองรับ Dependabot แต่ก็พบว่า Renovate ทำงานกับ Bun ได้ และเป็นตัวทดแทนที่เพียงพอในช่วงนี้
      ไม่เสียใจเลย ส่วนที่เร็วขึ้นซึ่งสะสมกันเป็นการประหยัดเวลา และการปรับปรุง developer experience ครั้งใหญ่ คุ้มค่าตามที่คาดไว้
  • คงมีคนไม่มากที่จะสังเกตว่าใส่ใจรายละเอียดกับเรื่องแบบนี้มากแค่ไหน ดีใจที่ได้เห็นว่าทีม Bun ใส่ใจ craft ของตัวเองมากเพียงใด

  • Bun น่าทึ่ง แต่เมื่อเร็ว ๆ นี้ผมพยายามสร้าง HTTP/2 server ด้วย Fastify แล้วทำไม่ได้
    มี error ว่า node:http2 createServer is not yet implemented in Bun และ issue ที่ข้อความชี้ไปจริง ๆ แล้วเกี่ยวกับการรองรับ HTTP/2 client ส่วนการรองรับ client ถูกปล่อยแล้วใน v1.0.13: https://bun.sh/blog/bun-v1.0.13#http2-client-support
    ข้อความ NotImplementedError ควรถูกเปลี่ยนให้ชี้ไปยัง issue ฝั่ง server: https://github.com/oven-sh/bun/issues/8823
    การรองรับ HTTP/2 server เป็นหนึ่งใน feature request อันดับต้น ๆ: https://github.com/oven-sh/bun/issues?q=is%3Aissue+is%3Aopen...
    ถ้าฟีเจอร์นี้ออกมา น่าจะทำให้คนย้ายมา Bun ได้มากขึ้นมาก

    • นั่นแหละคือสถานะของ Bun ตอนนี้ รอให้ implement เสร็จ แล้วหลังจากนั้นก็พบว่าต้องมี API implementation อื่นเพิ่มอีก พอรอต่อไปมันก็ออกมา แต่เกิด crash ใน edge cases หลายแบบ แล้วก็ต้องรอต่อ วนไปแบบนี้
      Bun ยังอยู่ในช่วงต้นของวงจรชีวิตมากเกินไป แต่ถึงอย่างนั้นก็ยังคาดหวังกับโปรเจกต์นี้มาก
  • สงสัยว่ามีคนใช้ Bun จริง ๆ ไหม ดีอย่างที่คาดหวังหรือเปล่า?

    • ยังไม่เคยใช้ใน production แต่สำหรับสคริปต์ครั้งเดียวและ side project มันดีมาก
      การตั้งค่าสภาพแวดล้อม TypeScript Node อย่าง ts-node, ts-jest, การรองรับ ESM, top-level await ฯลฯ ยุ่งยากเกินจำเป็น แม้ Node รุ่นล่าสุดจะลดความไม่สะดวกบางอย่างลงแล้ว แต่ก็ยังไม่ง่ายเท่า bun init ผมยังใช้ bun shell API อย่างสนุกด้วย: https://bun.sh/blog/the-bun-shell
    • ถ้าไม่ต้องใช้ REPL หรือไม่มีแผนใช้ native modules ก็โอเค แม้จะบอกว่ามี REPL แต่ทุกครั้งที่อัปเดตก็มักหน่วงเกิน 6 วินาทีเสมอ จึงไม่สะดวกมาก
      error message ก็แย่กว่า Node ค่อนข้างมาก ผมลองใช้อยู่พักหนึ่ง แต่ช่วงนี้ใช้ Node กับ —loader tsx ก็ทำทุกอย่างที่ต้องการได้หมดและไม่มีข้อเสีย ถ้าเป็น server ง่าย ๆ เช่นใช้ WebSocket และมั่นใจว่าไม่ต้องใช้ native modules ก็พิจารณา Bun ได้ จริง ๆ ผมก็รันบริการแบบนั้นอยู่สองสามตัว
    • เริ่มใช้ทันทีที่ 1.0 ออกมา และไม่ได้ย้อนกลับไปอีก ตอนนี้กำลังนำไปใช้กับทุกโปรเจกต์
    • ใช้เป็นตัวรันสำหรับการพัฒนาและทดสอบในโปรเจกต์ภาษาโปรแกรมมิงขนาดประมาณ 15,000 บรรทัด จนถึงตอนนี้ยังไม่เจอ ปัญหาเฉพาะของ Bun
      ความเร็วในการเริ่มทำงานทันทีนั้นยังน่าทึ่งอยู่
    • ใช้อยู่เมื่อไม่นานนี้และดีมาก การ ปรับปรุงคุณภาพชีวิต อย่างการไม่ต้องกังวลเรื่องการคอมไพล์ TypeScript นั้นสะดวกจริง ๆ และยังเร็วด้วย
      ยังมีบางอย่างที่ขาดอยู่ แต่สำหรับผมตอนนี้ดีกว่า Node แล้ว
  • บทความนี้ยังรู้สึกว่าเป็น กรณีศึกษา Zig ที่ยอดเยี่ยมด้วย น่าสนใจมาก

  • Bun ต้องดาวน์โหลดแพ็กเกจ 37 ตัวก่อนจะใช้ REPL ได้ ถ้าไม่มีอินเทอร์เน็ตก็ใช้ REPL ไม่ได้
    เมื่อรัน bun repl จะขึ้น error ว่าดาวน์โหลด package manifest ของ bun-repl ไม่สำเร็จ ไม่ใช่ปัญหาใหญ่ แต่ผมคาดหวังและตั้งตารอไว้มากว่าถ้าแค่ใส่ executable ไฟล์เดียวไว้ใน PATH ก็ควรทำงานได้ทันทีโดยไม่ต้องติดตั้งอะไร

    • ยังไม่ได้จัดลำดับความสำคัญให้การ implement REPL ตอนนี้ REPL คือ แพ็กเกจ npm bun-repl ที่ชุมชน implement
      ภายใน bun repl ทำสิ่งเดียวกับ bunx bun-repl