ขนมปังกลมต้นฉบับกำลังสับรางระหว่างประตูรันตรงกับทางแยกนำเข้าโมดูลบนโต๊ะสว่าง

Bun.main: แยกไฟล์ที่ถูกรันตรงจากไฟล์ที่ถูก import

พี่โชว์Engineering

โมดูลที่ทั้ง export ฟังก์ชันและทำงาน CLI มักเผลอรัน side effect ตอน test import ครับ Bun.main บอก path ของ entrypoint เราจึงเทียบกับ import.meta.path เพื่อเปิดการทำงานเฉพาะเมื่อไฟล์นี้ถูกเรียกตรง

WHY: แยก library surface ออกจาก process lifecycle

คิดเหมือนร้านที่มีประตูพนักงานกับประตูลูกค้า การ import ควรหยิบสูตรไปใช้โดยไม่เปิดร้าน ส่วนการรันไฟล์ตรงค่อยอ่าน argument, เขียน stdout และกำหนด exit code

export function normalizeName(value: string): string {
  return value.trim().toLowerCase();
}

export function isEntrypoint(): boolean {
  return Bun.main === import.meta.path;
}

if (isEntrypoint()) {
  console.assert(normalizeName("  Mint ") === "mint");
  console.assert(Bun.main.endsWith(".ts"));
}

อย่าผูก business logic กับ argv

ให้ main() ทำหน้าที่แปลง input/output แล้วเรียกฟังก์ชันบริสุทธิ์ การทดสอบจึง import function โดยไม่เปิด server หรืออ่าน secret อัตโนมัติ หาก bundle หรือ launcher เปลี่ยน path ให้เขียน integration test กับ artifact จริงด้วย เพราะ entrypoint ของ source และ output อาจไม่ใช่ไฟล์เดียวกัน

Node.js มีรูปแบบเทียบ import.meta.url กับ argv แต่บน Bun ใช้ Bun.main ทำ intent ตรงกว่า และรองรับ runtime contract ของ Bun โดยตรง

Recap

  • เทียบ Bun.main กับ import.meta.path
  • ให้ side effect อยู่หลัง entrypoint guard
  • แยก parser/business logic เป็นฟังก์ชัน import ได้
  • ทดสอบ artifact หลัง bundle เมื่อ path เปลี่ยนได้