JavaScript bundler ที่พัฒนาขึ้นแบบไหลไปตามสำนึก (Zig Native typescript Transpiler & Compiler)
(github.com/ohah)ในยุคของ AI ควรเรียนรู้อย่างไรดี?
ผมยังจับทางไม่ได้ว่าต้องการความเชี่ยวชาญแบบไหน หรือทักษะแบบใดที่มีคุณค่ามากที่สุดในยุคนี้
ทั้งบริษัทที่จ้างนักพัฒนาและตัวนักพัฒนาเอง ก็น่าจะไม่รู้เกณฑ์ที่ชัดเจนเหมือนกัน
อย่างไรก็ตาม ผมรู้สึกว่าถ้าอยู่นิ่ง ๆ ก็เสียเปล่าแน่นอน
เลยคิดว่าอย่างน้อยลองทำอะไรสักอย่างดู
ตอนแรกเริ่มจากการทำ Chrome Remote DevTools แบบง่าย ๆ เพื่อใช้เรียนรู้
พอทำไปก็คิดว่าลองทำให้ React Native รองรับผ่าน remote debugger ได้ด้วยดีกว่า
-> ไม่รู้จัก Metro เลย สับสนมาก
-> ลอง clone coding Metro ไปพร้อมกับศึกษา
-> จะทำ bundler ที่ดีกว่า Metro สำหรับ React Native ได้ไหม?
-> ลองจับนู่นจับนี่ผ่าน rolldown, swc, bun แล้วพยายามทำ bundler ที่ดีกว่า Metro bundler
ที่พอมีแววก็มี bun กับ rolldown แต่ก็รู้สึกถึงข้อจำกัดในการต้องปรับแต่งฝั่งเมนหลักเยอะ ๆ หรือ fork ออกมา
แถมก็ยังไม่มี web bundler ที่เข้ากันได้กับ Metro bundler แบบสมบูรณ์ ไม่ว่าจะเป็น Flow, ไวยากรณ์ JavaScript ที่ Hermes engine ยอมรับ หรือแม้แต่ลำดับการเรียกที่สำคัญซึ่งต่างจากเว็บทั่วไป
อา... ไหน ๆ ก็ถือว่าเรียนรู้อยู่แล้ว งั้นทำ bundler เองเพื่อมาแทน React Native Metro ไปเลยดีกว่า
สิ่งที่รู้สึกได้ระหว่างทำ bundler
งั้นรองรับเว็บไปด้วยเลยไม่ใช่เหรอ?
ใส่ ES5 ที่ rolldown ยอมแพ้ไปแล้วด้วย
ต้องรัน RN ก็เลยรองรับ Flow parser ด้วย
รองรับ wasm ด้วย
เรื่องความเร็วก็ลองเอาชนะ bun กับ rolldown ให้ได้
ใส่ HMR ของตัวเองด้วย
ลองทำ tree-shaking ให้ดุดันขึ้นอีกหน่อย
ทำ minify ให้ดูดีกว่า bundler อื่น ๆ
ผมพัฒนามันด้วยความคิดว่า อย่างน้อยใน benchmark และฟีเจอร์ที่ผมรับรู้ ก็ควรชนะ bundler ที่มีอยู่ทั้งหมดให้ได้
แน่นอนว่าก็คิดว่าน่าจะแพ้อยู่ในหลายจุด
เมื่อเทียบกับ bundler อื่น ๆ ไม่ว่าจะเป็นความเสถียร ฟีเจอร์ ecosystem และชุมชนที่รองรับ รวมถึง tree-shaking หรือ minify ที่กล่าวไปข้างต้น ซึ่งบางโมดูลก็ดีกว่าแต่บางโมดูลก็ยังตามหลังอยู่ ก็แน่นอนว่ายังมีส่วนที่ไม่สมบูรณ์อีกมาก
แต่จากผลการทดสอบการใช้งานในระดับหนึ่ง ก็มีบางส่วนที่ทำได้ดีกว่า และแม้จะยังมีงานอีกมากที่ต้องทำ (SSL, MCP, CLI, การทำให้เสถียร, เอกสาร API ฯลฯ) แต่เป้าหมายเดิมอย่างการ build และรันแอป React Native นั้น หลังจากลองกับแอปเชิงพาณิชย์ 3 ตัว ทั้ง release build, development build และ development server ก็ยืนยันได้ว่าทำงานได้ปกติดี เลยคิดว่าน่าจะถึงเวลาปล่อยออกมาแล้วค่อยพัฒนาต่ออย่างต่อเนื่อง จึงเขียนโพสต์นี้ขึ้นมา
อย่างน้อยฝั่งการพัฒนาและความสามารถด้าน bundle (zntc เองก็ build และแจกจ่ายด้วย zntc) ก็ทำงานได้ค่อนข้างดี
ฟีเจอร์สำคัญอย่าง decorators และฟีเจอร์กึ่งจำเป็นใน React Native อย่าง worklet, typescript, flow ฯลฯ ก็ทำงานได้ปกติดีกับไลบรารีที่ทดสอบ
ยังมีปลั๊กอินสำหรับ vite และ rspack ให้ด้วย มีสภาพแวดล้อมสำหรับการพัฒนา (RN, Web) แบบเดียวกับ vite, rspack มีเอกสาร มี React HMR และรองรับ module federation เป็นต้น
ดังนั้นผมจึงคิดว่าอย่างน้อยมันก็น่าจะมีฟังก์ชันพื้นฐานที่ bundler และ transpiler ควรมีอยู่พอสมควร เลยอยากเปิดเผยออกมาเพื่อรับ feedback และจะพัฒนาต่อไปหลังจากนี้
โค้ดที่เขียนด้วยมือตรง ๆ มีอยู่ 0 บรรทัด ทุกอย่างพัฒนาขึ้นมาจากการถกเถียงอย่างดุเดือดกับ AI
รู้สึกว่าใช้งาน AI หนักกว่าตอนพัฒนาผลิตภัณฑ์ไหน ๆ เสียอีก
ตอนแรกใช้แต่ Claude แล้วภายหลังก็ใช้ Codex ด้วย
ระยะเวลาพัฒนา bundler เองประมาณ 3 เดือน (ราว 3000 PR) ถ้ารวมเส้นทางความคิดไหลไปตามสำนึกที่เล่าไว้ด้านบนด้วย ก็น่าจะประมาณ 6 เดือนที่ทำแบบไม่แบ่งกลางวันกลางคืน
ทำงานทุกวันทั้งวันธรรมดาและวันหยุด และเพราะความรู้สึกกดดันจากการเอาไปเปรียบเทียบกับ bundler ตัวอื่นโดยไม่จำเป็น
ก็เลยพัฒนาแบบทุ่มสุดตัว ถึงขั้นเขียน test case จำนวนมากจนเรียกได้ว่าเกินเหตุ เพื่อให้ผ่าน test case หลากหลายแบบ เช่น test262 100%
รบกวนช่วยติชมกันเยอะ ๆ ครับ (__)
5 ความคิดเห็น
อีกทางเลือกแทน Metro ก็มี Re.Pack ที่ใช้ RSPack หรือ WebPack เช่นกัน
ตอนเขียนแบบไหลไปตามความคิดเลยลืมใส่ไว้ครับ
อย่างที่คุณบอก ผมก็อ้างอิง Re.pack ไว้เยอะเหมือนกัน
เท่าที่ทราบ ทั้ง Re.pack และ Rspack ต่างก็ใช้พื้นฐานจาก swc เลยไม่ได้รองรับ flow แบบเนทีฟ และในกรณีของ Re.pack ตั้งแต่เวอร์ชัน 5 เป็นต้นไป ผมเข้าใจว่ามี Rspack เป็นฐาน ซึ่ง Re.pack เองก็ยังใช้ swc+babel อยู่ ดังนั้นปลั๊กอินยอดนิยมอย่าง flow, reanimated และ nativewind (zntc มีแผนจะรองรับ) ก็ยังถูกทรานส์ไพล์ด้วย Babel อยู่เหมือนเดิม
ส่วนตัวผมอยากหลุดจาก Babel ก็เลยทำให้ zntc เป็นตัวเลือกที่รองรับได้ในตัวเป็นพื้นฐาน
แม้ zntc จะรองรับความเข้ากันได้กับ Babel ด้วย แต่ผมก็อยากลดการพึ่งพา Babel ให้เหลือศูนย์ถ้าเป็นไปได้
ถึงจะเป็นโค้ดที่เสถียรและผ่านการพิสูจน์มาแล้ว แต่ด้วยข้อจำกัดที่เป็น JavaScript มันเลยมีคอขวดด้านความเร็วอยู่เสมอ
จริง ๆ ตอนพัฒนาผมก็เทียบเบนช์มาร์กกับบันเดลเลอร์อื่น ๆ ไปตลอด และจากที่สัมผัสได้ด้วยตัวเองอย่างต่อเนื่อง ก็แน่นอนว่าเมื่อเทียบกับบันเดลเลอร์อื่นแล้ว ทั้งฟีเจอร์ ความเสถียร และความสามารถในการขยายต่อยังด้อยกว่าอยู่ ดังนั้นผมตั้งใจจะปรับปรุงส่วนนี้ต่อไปเรื่อย ๆ
แต่เนื่องจากมีการฝังความเข้ากันได้กับพาร์เซอร์ของไลบรารีหลัก ๆ ของ React Native มาในตัวอยู่แล้ว ผมเลยคิดว่าในจุดที่เป็นคอขวดเชิงโครงสร้างซึ่ง Re.pack เลี่ยงไม่ได้ ตรงนี้เรายังทำได้ดีกว่าอยู่ครับ!
น่าจะเป็นโปรเจกต์ที่ไม่ง่ายเลย เป็นกำลังใจให้นะครับ
ขอบคุณครับ!!
อืม... test262 100% งั้นเหรอ... เห็นแค่แบดจ์ก็นึกว่าระดับ V8 ซะอีก 555