Back

Ripple:一个值得关注的新型 TypeScript UI 框架

Ripple:一个值得关注的新型 TypeScript UI 框架

如果你曾花时间与 React 的 useMemouseCallback 以及陈旧闭包 bug 作斗争,你一定已经了解手动管理响应式所带来的心智负担。Ripple 是一个由 Dominic Gannaway(React Hooks 贡献者、Inferno 作者、Svelte 5 核心维护者)创建的新型 TypeScript 框架,它采用了完全不同的方法:通过编译消除响应式复杂性,让框架处理其余部分。

以下是它在技术上的有趣之处。

核心要点

  • Ripple 是一个编译器驱动的 UI 框架,使用 .ripple 文件并生成细粒度的 DOM 更新逻辑——无需虚拟 DOM 或协调过程。
  • 其响应式模型以 track()@ 访问操作符为核心,消除了对依赖数组、useMemouseCallback 的需求。
  • 响应式集合(#[]#{})允许直接变更并自动触发 UI 更新。
  • 该框架提供了完善的开发者工具(Vite 集成、VSCode 扩展、作用域样式),但仍处于早期实验阶段——值得研究学习,但尚未做好生产环境准备。

什么是 Ripple UI 框架?

Ripple 是一个编译器驱动的 UI 框架,围绕 .ripple 文件构建——这是它自己的模块格式,区别于 .tsx.jsx。Ripple 的编译器不是在运行时提供虚拟 DOM 和 diff 算法,而是分析组件并生成在运行时执行的细粒度 DOM 更新逻辑。

没有协调过程。没有组件重新运行。只有对确切变更节点的精确更新。

其结果是一个在概念上介于 Solid(细粒度信号)和 Svelte(编译器驱动输出)之间的框架,但从一开始就将 TypeScript 视为一等公民——而不是事后添加。

Ripple 的细粒度响应式工作原理

Ripple 的细粒度响应式模型围绕两个基本概念:

  • track() — 创建响应式值或派生计算
  • @ — 用于读取和写入被追踪值的访问操作符
import { track } from 'ripple'

export component Counter() {
  let count = track(0)
  let double = track(() => @count * 2) // 自动派生,无需依赖数组

  <div>
    <p>{@count}</p>
    <p>{@double}</p>
    <button onClick={() => @count++}>{"Increment"}</button>
  </div>
}

@count 改变时,只有依赖它的 DOM 节点会更新。double 自动重新计算。没有 useMemo,没有依赖数组,没有需要调试的陈旧闭包。

这与 React 的模型有本质区别,React 中状态变化会触发整个组件重新执行;也不同于 Solid 的 createSignal,Ripple 刻意避免模仿它。track() 这个命名传达了不同的心智模型:你在声明一个被追踪的关系,而不是手动连接信号图。

对于响应式集合,Ripple 引入了 #[](TrackedArray)和 #{}(TrackedObject),它们允许直接变更:

const todos = #[]
todos.push({ id: 1, text: 'Write docs', completed: false }) // UI 自动更新

无需展开操作符。无需 setState。直接变更即可。

Ripple TS 前端框架的开发者体验

Ripple 提供了专注但实用的工具链:

  • CLI 脚手架:npm create ripple my-app 可在几秒内获得一个由 Vite 驱动的项目
  • VSCode 扩展:在 .ripple 文件中提供智能感知、诊断和错误高亮
  • Prettier 和 ESLint 支持:对 .ripple 模块提供完整的格式化和代码检查
  • 作用域样式:组件内的 <style> 块自动限定作用域,无需配置 CSS Modules

组件使用 component 关键字而非 function,模板是语句而非返回值——这个微妙的转变为编译器提供了更多优化空间:

component Button(props: { text: string, onClick: () => void }) {
  <button onClick={props.onClick}>{props.text}</button>
}

控制流使用纯 JavaScript:for 循环、if/else 块和用于错误边界的 try/catch——无需 .map() 技巧或 <Show> 包装组件。

关于服务端渲染:Ripple 的文档提到了 render(服务端)和 hydrate(客户端)API,因此 SSR 是设计方向的一部分。但围绕它的生态系统还处于早期发展阶段,这不是一个你今天就能用于生产环境的框架。

结论

Ripple 是一个来自具有罕见框架开发经验者的真正技术实验。其核心理念——惰性响应式求值、编译器拥有的依赖追踪、TypeScript 原生语法——即使你永远不会为生产环境编写一行 Ripple 代码,也值得理解。

如果你感兴趣,GitHub 仓库文档是正确的起点。启动 Vite 脚手架,构建一个计数器或小型表单,看看这个心智模型是否适合你。

有趣的框架很少会大声宣告自己。它们只是让你以不同的方式思考你已经在使用的框架。

常见问题

React 在状态变化时重新执行整个组件,并依赖 useMemo 等 hooks 进行优化。Solid 使用细粒度信号但需要手动创建信号。Ripple 将编译器驱动的分析与其 track() 原语和 @ 操作符相结合,在构建时生成精确的 DOM 更新,完全消除了对依赖数组或手动记忆化的需求。

否。Ripple 是一个早期实验性框架。虽然其工具链包括 Vite 集成、VSCode 扩展和作用域样式,但生态系统仍在发展中。目前最适合用于探索和学习,而非交付生产应用。

TrackedArray (#[]) 和 TrackedObject (#{}) 是 Ripple 中的响应式集合原语。它们允许你使用标准操作(如 push 或属性赋值)直接变更数据,UI 会自动更新。这消除了 React 中常见的不可变更新模式、展开操作符或 setState 调用的需求。

Ripple 的文档提到了 render 和 hydrate API,表明 SSR 是框架设计方向的一部分。然而,SSR 方案仍处于早期阶段。目前还没有类似 Next.js 或 SvelteKit 那样成熟的元框架或经过生产验证的 SSR 管道可用于 Ripple。

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay