- เฟรมเวิร์ก UI ที่ปลอดภัยด้านชนิดข้อมูล ซึ่งรวม ข้อดีของ React·Solid·Svelte เข้าไว้ด้วยกัน โดยสร้างคอมโพเนนต์ด้วยแนวคิด ออกแบบแบบ JS/TS-first และภาษามอดูล
.ripple ของตัวเอง
- มุ่งเน้นประสิทธิภาพและการใช้หน่วยความจำอย่างคุ้มค่าด้วย ตัวแปร/พร็อพเพอร์ตีแบบ reactive ที่ใช้คำนำหน้า
$, เทมเพลตคล้าย JSX และ การเรนเดอร์แบบละเอียด
- มี VS Code extension, Prettier, และ การผสานรวมกับ TypeScript พร้อมทั้ง DX สมัยใหม่ เช่น reactive array·map·set, side effect แบบ
effect, และ decorator (@use)
- ขณะนี้ยังอยู่ในช่วง alpha ระยะแรก และมีข้อจำกัด เช่น ยังไม่รองรับ SSR และ ชนิดข้อมูลยังไม่ครบถ้วน โดยเปิดให้ใช้งานเพื่อทดลองแนวคิดและรับฟีดแบ็ก
- ด้วยแนวคิดที่คล้ายกับ runtime แบบ signal ของ Svelte 5 ทำให้มองเห็นทิศทางวิวัฒนาการของเฟรมเวิร์กฝั่งฟรอนต์เอนด์ ผ่านการทดลองแนวทาง JS/TS-first และ ไวยากรณ์ที่เป็นมิตรกับ LLM
What is Ripple?
- Ripple คือ เฟรมเวิร์ก UI แบบ TypeScript-first ที่ได้รับแรงบันดาลใจจาก React·Solid·Svelte และสร้างอยู่บน ภาษาซูเปอร์เซ็ต ที่ใช้ส่วนขยาย
.ripple ของตัวเอง
- ใช้ไวยากรณ์ที่เข้ากับ JSX ได้ดี โดยใช้ เทมเพลตภายในเนื้อหาของคอมโพเนนต์เท่านั้น และเลือกใช้ เทมเพลตแบบ statement แทนการคืนค่าแบบ JSX return
- ผู้สร้างได้นำแนวคิดนี้มาสร้างในรูปแบบ เชิงทดลอง จากประสบการณ์กับ Inferno·React Hooks·Lexical·Svelte 5 เป็นต้น
- ขณะนี้ยังอยู่ใน ช่วงพัฒนาเริ่มต้น มีบั๊กและ TODO จำนวนมาก และ ไม่แนะนำให้ใช้ใน production
- จุดประสงค์คือ แบ่งปันแนวคิดและบ่มเพาะไอเดีย รวมถึงสำรวจความเป็นไปได้ในการส่งต่อไปยังเฟรมเวิร์กอื่น
- เป็นความพยายามในการทดสอบสมมติฐานว่าแนวทาง JS/TS-first จะมอบ DX ที่ดีทั้งต่อมนุษย์และ LLM
Features
- Reactive State Management: รองรับ reactivity ของตัวแปรและพร็อพเพอร์ตีของอ็อบเจ็กต์ด้วยคำนำหน้า
$ และสามารถเขียน ค่าที่คำนวณต่อยอด เป็นตัวแปร $ ได้อย่างเป็นธรรมชาติ
- Component-Based Architecture: ประกาศคอมโพเนนต์อย่างชัดเจนด้วยคีย์เวิร์ด
component, รองรับ props/children และผสานกับ เทมเพลตคล้าย JSX
- Performance: มุ่งสู่ประสิทธิภาพและการใช้หน่วยความจำระดับแนวหน้าของอุตสาหกรรมด้วย การเรนเดอร์แบบละเอียด (fine-grained)
- Tooling: รองรับ การผสานรวมกับ TypeScript, VS Code IntelliSense/การวินิจฉัย/ไฮไลต์, และการฟอร์แมตด้วย Prettier
- เสริม DX: ยึดแนวคิด JS/TS-first, ไวยากรณ์ที่เป็นมิตรกับ LLM, และมีโครงสร้าง SPA เป็นค่าเริ่มต้น
Missing Features
- ไม่มี SSR: ขณะนี้รองรับเฉพาะ SPA เท่านั้น และยังไม่ได้พัฒนา SSR
- ชนิดข้อมูลยังไม่ครบ: นิยามชนิดข้อมูล ภายในโค้ดเบสยังมีจำกัด และมีแผนจะปรับปรุงต่อไป
Getting Started / Try Ripple
- สามารถเปิดเทมเพลตพื้นฐานใน StackBlitz หรือโคลนด้วย
degit แล้วรันผ่าน Vite development server
- ตัวอย่างคำสั่ง:
npx degit trueadm/ripple/templates/basic my-app → npm i → npm run dev
- ออนไลน์ playground จะมีเพิ่มในภายหลัง และตอนนี้สามารถทดลองแบบโลคัลได้ผ่านโฟลเดอร์
playground ในรีโป
VSCode Extension
- มี extension Ripple for VS Code สำหรับไฟล์
.ripple พร้อมรองรับ syntax highlighting, การวินิจฉัยแบบเรียลไทม์, การผสานรวมกับ TS, และ auto-completion (IntelliSense)
- มีทั้งลิงก์สำหรับเวอร์ชันบน Marketplace และแพ็กเกจ
.vsix สำหรับติดตั้งด้วยตนเอง
Mounting your app
- รองรับการเมานต์รูทคอมโพเนนต์ที่จุดเริ่มต้นด้วยรูปแบบ
mount(App, { props, target })
- มี API ที่กระชับสำหรับกำหนด DOM node ผ่าน
target และส่งค่าเริ่มต้นผ่าน props
Key Concepts
- Components
- ใช้คีย์เวิร์ด
component เพื่อกำหนด คอมโพเนนต์เชิงประกาศ ที่มีลายเซ็นคล้ายฟังก์ชัน และสามารถเขียน เทมเพลตคล้าย JSX ภายในเนื้อหา ได้โดยตรง
- รองรับ การเขียนพร็อพแบบย่อ (
{onClick}), spread ({...props}) และ ไวยากรณ์ที่คุ้นเคย อื่น ๆ
- Reactive Variables
- ตัวแปรและพร็อพเพอร์ตีที่ขึ้นต้นด้วย
$ จะมี reactivity อัตโนมัติ และสามารถกระตุ้นการเรนเดอร์ใหม่ได้ด้วยเพียง การเพิ่มค่าหรือการกำหนดค่าใหม่
- สถานะที่คำนวณต่อยอด สามารถประกาศด้วยรูปแบบที่เข้าใจง่าย เช่น
$double = $count * 2 และยังรองรับ การคำนวณต่อยอดแบบเป็นลูกโซ่
- สามารถใช้
untrack เพื่อ ปิดกั้นการแพร่กระจายของ reactivity ในบางช่วง เช่น ตอนเริ่มต้นค่า
- ห้ามใช้ตัวแปร reactive ใน global/ระดับบนสุดของโมดูล และต้องสร้างภายใน active component context เท่านั้น
- Transporting Reactivity
- สามารถ พา reactivity ข้ามขอบเขต ได้ด้วยการห่อ array·object ทำให้ จัดองค์ประกอบและอยู่ร่วมกัน ได้ง่าย
- แนะนำแพตเทิร์นที่ให้ฟังก์ชัน factory รับค่า
$, สร้าง derived/effect ภายใน แล้ว คืนค่า $ กลับมา
- Reactive Arrays / Set / Map
RippleArray/Set/Map คือ คอลเลกชันแบบ reactive ที่ต่อยอดจากคอลเลกชันมาตรฐาน โดยการเข้าถึงความยาว/ขนาดต้องใช้ $length/$size จึงจะเป็น reactive
- สามารถใช้ผลลัพธ์จากเมธอด โดยตรง หรือกำหนดลงใน ตัวแปร reactive เช่น
$has เพื่อนำไปใช้ในเทมเพลต
- Effects
- ใช้
effect(() => { ... }) เพื่อประกาศ side effect ที่จะทำงานเมื่อค่า $ ที่พึ่งพาเปลี่ยน พร้อม การติดตาม dependency แบบอัตโนมัติ
- Control flow
- เทมเพลตอนุญาตให้ใช้ ภายในเนื้อหาคอมโพเนนต์เท่านั้น และจะไม่ คืนค่า JSX เอง ผ่านฟังก์ชันทั่วไปหรือการกำหนดตัวแปร
- ภายในเทมเพลตสามารถใช้ การประกาศตัวแปร/การเรียกฟังก์ชัน/
debugger ได้ และรองรับ control flow แบบเน้น statement
- ใช้กติกาที่ให้ string literal ต้องเขียนเป็น
{ "…" } เพื่อแยกออกจากโค้ดอย่างชัดเจน
- If / For / Try statements
- ใช้
if/else ภายในบล็อกเทมเพลต เพื่อสร้าง control flow ที่ อ่านง่าย
- รองรับ
for...of สำหรับ เรนเดอร์คอลเลกชัน โดยไม่จำเป็นต้องมี key prop
- ใช้บล็อก
try/catch เพื่อสร้าง error boundary (fallback UI) และสามารถ log·report ใน catch ก่อน เรนเดอร์ UI ทดแทน
- Props
- พร็อพแบบ reactive ต้องใช้คำนำหน้า
$ และแอตทริบิวต์ DOM ก็ต้องใส่คำนำหน้าเช่น $class, $id จึงจะอัปเดตแบบ reactive ได้
- Children
- มีสล็อตคอมโพเนนต์แบบ implicit
$children และสามารถใช้ <$children /> เพื่อทำ composition
- ยังสามารถประกาศสล็อตคอมโพเนนต์แบบ explicit ได้ เพื่อให้ได้ทั้ง ความอ่านง่ายและการควบคุมที่ดีขึ้น
- Events
- รองรับ Event API คล้าย React (
onClick, onKeyDown, …Capture) และบางอีเวนต์ถูกปรับแต่งด้วยการ delegate เพื่อประสิทธิภาพ
- Decorators
- ใช้ ไวยากรณ์ decorator
{@use fn} เพื่อรับ การอ้างอิงถึง DOM node จริง และสามารถคืนค่า hook สำหรับ mount/unmount ได้
- รองรับแพตเทิร์นการ ส่งค่าที่ reactive ผ่าน inline function/factory และการ ส่งต่อไปยังคอมโพเนนต์แบบ composite
- Styling
- สามารถเขียน CSS แบบ local scope ต่อคอมโพเนนต์ ในบล็อก
<style> ระดับบนสุด เพื่อให้ได้ การจัดการสไตล์แบบห่อหุ้ม
- Context
- ใช้
createContext เพื่อกำหนด ค่าที่แชร์กันในต้นไม้คอมโพเนนต์ระดับบน-ล่าง และอนุญาตให้ get/set ได้เฉพาะภายในคอมโพเนนต์ เพื่อความคาดเดาได้
Playground
- หลังโคลนรีโปแล้ว สามารถรัน local playground ได้ด้วย
pnpm i && cd playground && pnpm dev
- ใช้ Vite plugin เพื่อให้ทดลองไวยากรณ์
.ripple ใน playground/src ได้อย่างสะดวก
Why it matters
- แนวคิดอย่าง JS/TS-first · เทมเพลตแบบ statement-style · reactivity แบบคำนำหน้า
$ เป็นการทดลองที่พยายามรวม โครงสร้างโค้ดที่เป็นมิตรกับ LLM เข้ากับ ความอ่านง่ายและการวิเคราะห์แบบสแตติก
- การผสมผสานอย่าง การเรนเดอร์แบบละเอียด · reactivity ของคอลเลกชัน · การ hook DOM ด้วย decorator คือความพยายามในการทำให้ การปรับแต่งระดับละเอียดและ DX ไปด้วยกันได้
- แม้ยังอยู่ใน ขั้น alpha แต่ก็ช่วยให้เห็นมุมมองอ้างอิงสำหรับ การออกแบบเฟรมเวิร์กรุ่นถัดไป ผ่านการตรวจสอบข้ามกันระหว่าง แนวทางแบบ signal ของ Svelte 5 และ ประสบการณ์การพัฒนาในระบบนิเวศของ React
3 ความคิดเห็น
เหมือนจะดี แต่ก็เหมือนจะไม่ดีเหมือนกัน
ให้ความรู้สึกคล้าย Svelte มากเลยนะครับ
วนไปวนมาสุดท้ายอาจจะไปจบที่แนว ReactLike ก็ได้ 555
ดูเหมือนว่าตอนนี้หลายคนเริ่มเลี่ยงเฟรมเวิร์กใหม่ ๆ เพราะมีข้อมูลที่ AI ใช้เรียนรู้น้อยเกินไป
ผมคิดว่า Svelte คือขบวนสุดท้ายแล้ว แม้แต่ Svelte เอง ถ้าเขียนพรอมป์ต์ไม่ดี มันก็ชอบพุ่งเข้าใส่ไวยากรณ์
$โดยไม่ใช้ rune อยู่เรื่อย ๆ จนลำบากครับ