用最直觀的語法,構建最高效的 Web 應用
AI 時代,更需要精品框架
2026 年,AI 編程已經成為常態。Cursor、Claude、Copilot……開發者每天都在用 AI 生成大量代碼。
但這帶來了一個新問題:代碼量爆炸,質量卻在下降。
AI 可以快速生成代碼,但它生成的往往是"能跑就行"的代碼——冗餘的狀態管理、不必要的重渲染、臃腫的依賴。當項目規模增長,這些問題會被放大。
AI 時代不缺代碼,缺的是精品框架——能夠約束代碼質量、保證性能、減少出錯的框架。
現有框架的問題
// React: 樣板代碼太多
function Counter() {
const [count, setCount] = useState(0)
const increment = useCallback(() => {
setCount(prev => prev + 1)
}, [])
return <button onClick={increment}>{count}</button>
}
// Vue: 需要記住 .value
const count = ref(0)
count.value++ // 忘記 .value 就出錯
// 這些"儀式感"代碼,AI 可能寫對,也可能寫錯
// 更重要的是:它們讓代碼變得臃腫
Ripple 的答案:少即是多
component Counter() {
let count = track(0);
<button onClick={() => @count++}>{@count}</button>
}
4 行代碼,零樣板。
- 沒有
useState/ref/signal - 沒有
useCallback/useMemo - 沒有
.value/$: - 編譯器自動優化,運行時極致精簡
| 指標 | React | Vue | Ripple |
|---|---|---|---|
| 計數器代碼行數 | 6-8 行 | 4-5 行 | 3 行 |
| 運行時大小 | ~40KB | ~30KB | ~5KB |
| 更新粒度 | 組件級 | 組件級 | 節點級 |
為什麼這在 AI 時代更重要?
- 代碼審查成本:AI 生成的代碼需要人工審查,越簡潔越好審
- 錯誤概率:語法越簡單,AI(和人)出錯的機會越少
- 性能兜底:即使 AI 不考慮性能,編譯器會幫你優化
- 可維護性:三個月後回看代碼,還能一眼看懂
Ripple 的設計哲學:代碼應該讀起來像它做的事情。
為什麼選擇 Ripple?
Ripple 追求兩全其美——既要 React 的組件模型和 JSX 表達力,又要 Svelte 的編譯時優化和極致性能。
看看這段代碼:
component Counter() {
let count = track(0);
<button onClick={() => @count++}>
{"點擊了 "}{@count}{" 次"}
</button>
}
這就是 Ripple。沒有 useState,沒有 $:,沒有 .value。track() 創建狀態,@ 讀寫值,簡潔直觀。
核心理念
1. 編譯器優先
Ripple 不是一個運行時框架,而是一個編譯器。你寫的代碼會被轉換成高效的 JavaScript:
你寫的代碼 編譯後的代碼
───────────── ─────────────
let count = track(0) → var count = _$_.tracked(0)
{@count} → _$_.get(count)
@count++ → _$_.update(count)
這意味着:
- 零運行時開銷:響應式追蹤在編譯時完成
- 更小的包體積:沒有虛擬 DOM diff 算法
- 更快的更新:直接操作需要更新的 DOM 節點
2. 組件即函數
在 Ripple 中,組件就是帶有 component 關鍵字的函數:
component Greeting({ name = "World" }) {
<h1>{"Hello, "}{name}{"!"}</h1>
}
// 使用
<Greeting name="Ripple" />
3. 響應式狀態:track() 和 @ 語法
用 track() 創建響應式變量,用 @ 讀寫值:
component Form() {
let name = track("");
let email = track("");
<form>
<input value={@name} onInput={(e) => @name = e.target.value} />
<input value={@email} onInput={(e) => @email = e.target.value} />
<p>{"你好,"}{@name}{"!我們會發郵件到 "}{@email}</p>
</form>
}
4. 響應式集合:#[] 和 #{}
數組和對象也可以是響應式的:
const items = #[]; // 響應式數組
const user = #{ name: "Tom" }; // 響應式對象
const tags = new TrackedSet(["a", "b"]); // 響應式 Set
const cache = new TrackedMap([["k", "v"]]); // 響應式 Map
對這些集合的任何修改都會自動觸發 UI 更新:
items.push("new item"); // UI 自動更新
user.name = "Jerry"; // UI 自動更新
實戰:構建一個 Todo 應用
讓我們用 Ripple 構建一個完整的 Todo 應用,體驗框架的核心特性。
完整代碼
import { track } from 'ripple';
component TodoInput({ onAdd }) {
let value = track("");
function handleKeyDown(e) {
if (e.key === "Enter" && @value.trim()) {
onAdd(@value.trim());
@value = "";
}
}
<div class="input-section">
<input
type="text"
placeholder="Add a new todo..."
value={@value}
onInput={(e) => @value = e.target.value}
onKeyDown={handleKeyDown}
/>
<button onClick={() => { if (@value.trim()) { onAdd(@value.trim()); @value = ""; } }}>{"Add"}</button>
</div>
}
component TodoItem({ todo, onToggle, onDelete }) {
<li>
<input type="checkbox" checked={todo.completed} onChange={onToggle} />
<span class={todo.completed ? "done" : ""}>{todo.text}</span>
<button onClick={onDelete}>{"×"}</button>
</li>
}
export component App() {
const todos = #[];
function addTodo(text) {
todos.push(#{ id: Date.now(), text, completed: false });
}
function toggleTodo(todo) {
todo.completed = !todo.completed;
}
function deleteTodo(id) {
const index = todos.findIndex(t => t.id === id);
if (index > -1) todos.splice(index, 1);
}
const activeCount = () => todos.filter(t => !t.completed).length;
<div class="app">
<h1>{"Todo App"}</h1>
<TodoInput onAdd={addTodo} />
<ul>
for (const todo of todos) {
<TodoItem
todo={todo}
onToggle={() => toggleTodo(todo)}
onDelete={() => deleteTodo(todo.id)}
/>
}
</ul>
<p>{todos.length}{" total, "}{activeCount()}{" remaining"}</p>
</div>
<style>
.app { max-width: 400px; margin: 40px auto; font-family: system-ui; }
h1 { color: #e91e63; }
.input-section { display: flex; gap: 8px; margin-bottom: 16px; }
.input-section input { flex: 1; padding: 8px; }
ul { list-style: none; padding: 0; }
li { display: flex; gap: 8px; align-items: center; padding: 8px 0; }
li span { flex: 1; }
li span.done { text-decoration: line-through; color: #888; }
p { color: #666; font-size: 14px; }
</style>
}
代碼解析
1. 響應式數組 #[]
const todos = #[];
#[] 創建一個響應式數組。當你調用 push、splice、filter 等方法時,Ripple 會自動追蹤變化並更新 UI。
2. 響應式對象 #{}
todos.push(#{ id: Date.now(), text, completed: false });
每個 todo 項也是響應式對象,這樣 todo.completed = !todo.completed 就能觸發更新。
3. 控制流:內聯 for 和 if
for (const todo of todos) {
<TodoItem todo={todo} ... />
}
if (todos.some(t => t.completed)) {
<button>{"清除已完成"}</button>
}
Ripple 的控制流直接寫在 JSX 中,不需要 map 或三元表達式。編譯器會將其轉換為高效的 block 結構。
4. 作用域樣式
<style>
.todo-item { ... }
</style>
組件內的 <style> 標籤會被自動添加作用域哈希,不會污染全局樣式。
編譯產物一覽
好奇 Ripple 編譯器做了什麼?來看看 @count++ 這行代碼的旅程:
源碼 編譯階段 運行時
──── ──────── ──────
let count = track(0) → 解析為 AST → var count = _$_.tracked(0)
(TrackedExpression)
@count++ → 分析綁定類型 → _$_.update(count)
(kind: 'tracked')
{@count} → 轉換為渲染函數 → _$_.render(() => {
_$_.set_text(anchor, _$_.get(count))
})
三階段編譯流程:
- 解析 (Parse):將源碼轉為 AST,識別
@、#[]、component等特殊語法 - 分析 (Analyze):構建作用域、標記變量類型、裁剪未使用的 CSS
- 轉換 (Transform):生成客户端/服務端 JavaScript 代碼
與其他框架對比
| 特性 | Ripple | React | Vue 3 | Svelte |
|---|---|---|---|---|
| 響應式語法 | track() + @ |
useState |
ref().value |
$: |
| 虛擬 DOM | 無 | 有 | 有 | 無 |
| 編譯時優化 | 是 | 否 | 部分 | 是 |
| 包體積 | ~5KB | ~40KB | ~30KB | ~2KB |
| 學習曲線 | 低 | 中 | 中 | 低 |
| 控制流 | 內聯語法 | map/三元 | v-if/v-for | {#if}/{#each} |
| 樣板代碼 | 極少 | 多 | 中 | 少 |
編譯器:質量的守護者
Ripple 的編譯器不只是"翻譯"代碼,它是代碼質量的守護者:
1. 自動依賴追蹤
// 你只需要寫業務邏輯
const fullName = () => `${@firstName} ${@lastName}`
// 編譯器自動分析依賴,生成優化代碼:
// _$_.render(() => set_text(anchor, `${get(firstName)} ${get(lastName)}`))
不需要 useMemo([dep1, dep2]),編譯器比你更清楚依賴關係。
2. CSS 死代碼消除
component Button() {
<button class="primary">{"Click"}</button>
<style>
.primary { background: blue; }
.secondary { background: gray; } /* 編譯器自動移除 */
.danger { background: red; } /* 編譯器自動移除 */
</style>
}
不用擔心 CSS 越寫越多,編譯器只保留真正用到的樣式。
3. 細粒度更新
component Profile() {
const user = #{ name: "Tom", bio: "Developer" };
<div>
<h1>{user.name}</h1> {/* 只在 name 變化時更新 */}
<p>{user.bio}</p> {/* 只在 bio 變化時更新 */}
</div>
}
編譯器分析每個表達式的依賴,生成最精確的更新邏輯。
讓 AI 更懂 Ripple
Ripple 提供了 llms.txt,這是一份專為 AI 助手設計的框架説明文檔。
當你使用 Claude、ChatGPT 或其他 AI 助手時,可以讓它先閲讀這份文檔:
請先閲讀 https://www.ripplejs.com/llms.txt,然後幫我用 Ripple 框架實現一個 [功能描述]
llms.txt 包含:
- Ripple 核心語法速查
- 常見模式和最佳實踐
- 易錯點和正確寫法
- 完整示例代碼
這確保 AI 生成的代碼符合 Ripple 的設計理念,而不是用 React 的思維寫 Ripple。
快速開始
# 創建新項目
npx create-ripple-app my-app
cd my-app
# 啓動開發服務器
npm run dev
然後打開 src/App.ripple,開始編寫你的第一個 Ripple 組件!
寫在最後
AI 讓寫代碼變得更快了,但"更快"不等於"更好"。
當代碼生成的速度超過理解的速度,我們更需要:
- 精簡的語法 — 讓代碼量回歸理性
- 編譯時優化 — 讓性能有保障
- 直觀的心智模型 — 讓維護不再痛苦
Ripple 不是為了追逐新概念而生,而是對"前端開發應該是什麼樣"的一次回答。
少寫代碼,寫好代碼。
Ripple — 讓響應式迴歸簡單
GitHub · 文檔 · llms.txt