Ripple 运行时演进全解:从 CHANGELOG 追溯 Ripple 框架的版本史与源码实证
2026/9/16 18:45:19 网站建设 项目流程

Ripple 运行时演进全解:从 CHANGELOG 追溯 Ripple 框架的版本史与源码实证

【免费下载链接】ripplethe elegant TypeScript UI framework项目地址: https://gitcode.com/GitHub_Trending/ripple25/ripple

packages/ripple/CHANGELOG.md是 Ripple 核心运行时包的完整版本记录,从 0.2.209 一路覆盖到当前的 0.3.127。本文以该 changelog 为骨架,梳理ripple运行时包的关键演进脉络——编译体系拆分、响应式 API 定型、SSR 与流式渲染、作用域样式主题、列表协调与类型系统——并结合仓库中的 package.json 与 src/server/index.js 等源码逐条交叉印证,帮助读者在阅读版本历史的同时准确理解每一项变更在代码中的落点。

一、如何阅读这份 CHANGELOG

这份 changelog 采用 changesets 风格生成:每个版本小节下分Patch Changes/Minor Changes,每条变更附 PR 编号、commit 短哈希与贡献者,末尾统一列出Updated dependencies,登记该版本同步升级的关联包。

从依赖登记可以读出 Ripple 的分包结构:ripple运行时之外,还有两个编译器包长期跟随发版——

  • @tsrx/core:编译器核心基础设施(解析器工厂、作用域管理、工具与常量);
  • @tsrx/ripple:Ripple 专用编译器(客户端/服务端转换)。

这一结构在 0.3.14 版本的 changelog 条目中有明确说明(编译层从ripple包中抽出),后文会展开。

二、包现状:0.3.127 的公开 API 面

changelog 顶部记录的最新版本为 0.3.127("Align JSX component types with the publicComponenttype"),与 package.json 中的"version": "0.3.127"一致。该文件的exports字段定义了运行时的全部公开子路径,正好对应 changelog 中多个版本触及的 API 面:

子路径指向对应 changelog 里程碑
.(默认/浏览器/worker)src/runtime/index-server.js/index-client.js服务端与客户端双运行时
./serversrc/server/index.js0.3.93 的createStream/getCss重命名
./compilersrc/compiler/index.js0.3.22 恢复、0.3.14 抽出的编译层
./jsx-runtimesrc/jsx-runtime.jsJSX 类型对齐(0.3.127)
./internal/*./validator内部运行时与校验器供编译产物与 Vite 插件消费

其中./server值得单独看一下:src/server/index.js 开头三行就是 changelog 0.3.93 条目的活证据——

export { create_ssr_stream as createStream, render } from '../runtime/internal/server/index.js'; export { get_css_text as getCss } from '../runtime/internal/server/css-registry.js'; export { executeServerFunction } from '../runtime/internal/server/rpc.js';

0.3.93 的变更说明是:ripple/server的辅助导出由 snake_case 统一为 camelCase(create_ssr_streamcreateStreamget_css_for_hashesgetCss),旧导出被移除,升级时需同步修改 import。该文件同时还导出render及 SSR 用运行时,与 changelog 0.3.92 描述的流式 SSR 能力配套。

三、编译体系:从包内编译器到 TSRX 共享层

changelog 中有一条清晰的"编译层外迁"主线:

  1. 0.3.14:编译器从ripple包抽出为@tsrx/core@tsrx/ripple两个包,ripple包只保留运行时消费入口。
  2. 0.3.22:修复抽包时遗漏的ripple/compiler子路径导出(该路径曾被livecodes等下游工具按公开路径导入),恢复后重新导出@tsrx/ripplecompileparsecompile_to_volar_mappingsAPI,并把@tsrx/ripple提升为运行时依赖。
  3. 0.3.125:目标无关的 TSRX 源码进一步迁移到tsrx-org/tsrx,新 Ripple 项目改用已发布的@tsrx/language-server与已发布的 TSRX 集成;当前 package.json 的 dependencies 中@tsrx/core@tsrx/rippleworkspace:*)即是这条线的最终形态。

这条演进说明ripple包本身是"纯运行时 + 编译器再导出"的形态,编译能力实际由@tsrx/*承担,这也是为什么 changelog 中大量版本的Updated dependencies同时登记两个@tsrx/*包。

四、响应式模型:从#ripple命名空间到trackAsync

这是 changelog 中信息密度最高的一条主线,API 形态经历了多次收敛:

  • 0.3.0:引入#ripple命名空间,无需 import 即可创建响应式实体(array、object、map、set、date、url 等),并把TrackedArray/TrackedObject等类型改名为RippleArray/RippleObject

  • 0.3.4:新增惰性解构语法&{...}&[...]——属性/索引访问推迟到绑定被读取时才发生,从而保留解构 props 的响应性,且支持默认值、复合赋值与++/--(0.3.5 进一步修复了带默认值惰性绑定上的自增/自减)。同一版本移除#ripple命名空间,所有响应式 API 回归标准 import,changelog 给出了逐条映射:

    #ripple.track(value) → track(value) #ripple.effect(fn) → effect(fn) #ripple.untrack(fn) → untrack(fn) #ripple.context(value) → new Context(value) #ripple[1, 2, 3] → new RippleArray(1, 2, 3) #ripple{ key: value } → new RippleObject({ key: value }) #ripple.style → #style #ripple.server → #server

    对应写法:

    import { track, effect, untrack, Context, RippleArray, RippleObject } from 'ripple';
  • 0.3.7:追踪值的get()/set()API 被.valuegetter/setter 取代(覆盖运行时、类型与惰性解构测试)。

  • 0.3.13trackAsync()成为一等特性——组件级直接await被禁止,异步流程必须走trackAsync()(配trackPending()检查 pending 状态),try/catch/pending边界的客户端与 SSR 行为随之对齐。同一版本还引入.rsrx文件扩展名并全工具链改名。

  • 0.3.30:编译器弃用node:crypto,改为纯 JS 哈希实现以支持浏览器 Worker(如 Monaco playground):simple_hash(djb2,用于 CSS 类名前缀等高频短文本)与strong_hash(SHA-256 前缀,用于服务端文件系统路径派生的 RPC id 等,防止哈希反推原始路径);ripple运行时不再自带hashing.js,改为从@tsrx/core再导出。

  • 0.3.84:新增snapshot()API,为RippleArray/RippleObject生成非响应式的浅拷贝。这条可以在源码中直接验证——src/runtime/index-server.js 中的snapshot对非对象原样返回,对对象做[...value]{ ...value }浅拷贝(服务端值不经代理,浅拷贝即足够);src/runtime/proxy.js 中有客户端版本。

客户端/服务端的 API 对称性也值得注意:src/runtime/index-server.js 将track_async as trackAsyncis_tracked_pending as trackPending重导出,并把effecttick、各类bind*指令全部替换为noopRippleObject/RippleArray等退化为原生Object/Array——这正是 changelog 反复强调"同一 API 在客户端与 SSR 下语义对齐"的实现方式。

五、SSR 与流式渲染

  • 0.2.209:SSR 阶段加入 dev 模式下的非法 HTML 嵌套校验(如<button>嵌套<button>会被浏览器自动修复,导致 hydration 不可行)。实现上,服务端运行时提供push_element/pop_element维护元素栈,服务端编译产物在dev选项下发射校验调用,Vite 插件在vite dev时自动启用。
  • 1.0.1(changelog 中原样记录于 0.3.26 与 0.3.25 之间):为trackAsync增加 SSR→客户端序列化——按调用点发射 JSON<script>信封(已解析载荷 + 直接依赖哈希,或脱敏后的错误信息),客户端 hydration 时消费并移除,避免重跑用户异步函数;错误按开发/生产分别给出真实或安全消息并路由到 catch 块。changelog 0.3.13 描述的trackAsync/trackPending语义在此补齐了跨端闭环,src/utils/track-async-serialization.js 即为该序列化逻辑的落点。
  • 0.3.92:流式 SSR 落地——render(App, { stream })渐进式输出:同步外壳(含挂起@try边界的 pending 回退与已登记的 CSS)先冲刷,各边界内容以带帧块的形式乱序流出(含逐块 CSS、trackAsync信封与<head>内容);内联小运行时在 hydration 前把块换入槽位,hydration 后已激活的边界直接认领流式 DOM 而不重渲。render新增streamTemplate选项,Vite 插件在ripple.config.ts开启ssr.streaming时对流式路由响应,index.html缺少<!--ssr-head-->/<!--ssr-body-->标记时回退缓冲式 SSR。

六、作用域样式、主题与$class(0.3.126)

changelog 0.3.126 是最长的一条条目,记录了 TSRX RFC #1 在 Ripple 目标的实现,要点:

  • <style>块作用域限定于兄弟节点:样式其旁的元素及其下方一切内容,绝不作用于包含它的元素;同一子节点列表中的多个块共享一个哈希与一份样式表,嵌套子节点列表构成嵌套作用域,每个元素携带各层外层作用域哈希(外层在前);
  • 块被赋给变量后暴露$class;被导出、被apply或被读取$class的块成为"主题"(保留全部选择器),其余赋值块保持类映射;<style apply={theme} />将主题挂到整个作用域,带子内容的<style apply={theme}>…</style>一标签完成应用与声明,数组可应用多个主题,主题之间可以互相应用;
  • CSS 按词法顺序输出:被应用的主题先于应用它的块输出,同一作用域的块相邻输出,嵌套作用域位于父级之后;服务端 render 按该顺序登记所需样式表,theme.$class在 render 外读取不再抛错;
  • 修复了客户端@{ … }块作为 DOM 子节点被丢弃的问题;#class展开属性接受多个类 token。

配合 0.3.60 的编辑器改进(事件处理器类型推断、<style>存在时 DOM 属性补全失效的修复、跨 TSRX 目标共享 scoped CSS 选择器元数据、CMD+click 跳转到类定义),样式系统形成了从编译到编辑器支持的一致体验。

七、列表协调、锚点优化与 Portal 事件委托

changelog 中多条记录展示了运行时 DOM 协调的精细演进,适合作为阅读框架内部实现的案例:

  • 0.3.85:对"整个可渲染输出只是单个@if/@switch/@for/@try/静态子组件"的作用域(组件体、控制流分支等),编译器不再合成<!>片段包裹与额外 append + clone,而是直接渲染在父级提供的__anchor之前。changelog 自述 recursive-context 基准下每个元素降到一次 clone + 一次 append 的 DOM 操作,注释锚点节点减半;hydration 通过控制流运行时捕获 SSR 边界标记后再交给append()得以保持。同版本还把客户端 flush 遍历从全树扫描收窄到更新子树:flush_updates只沿路由路径下探到被调度的块,跨子树的追踪读取会在register_dependency中检测并透明回退到全树扫描。
  • 0.3.86:修复 0.3.85 优化引入的回归——带 key 的@for项体为单一控制流/组件根时s.start为 null,append()抛出Cannot use 'in' operator to search for 'parent' in null;协调过程改为下探子块解析真实首/末 DOM 节点,避免重新引入注释标记。
  • 0.3.123:修复 keyed/ref 型@for在列表中部批量插入时锚点漂移(如[A, C, D] → [A, B1, B2, C, D]曾被渲染为A, B1, C, B2, D):插入锚点现在于匹配后缀起点一次性解析并整段复用。
  • 0.3.124:Portal 事件委托改为按 target 计数引用——此前两个 Portal 挂到document.body时,先关闭的那个会拆掉整个 body 上的委托监听,导致另一个 Portal 内点击静默失效;同时移除了单一root_target全局,on()检查元素是否匹配所有活动根 target,Portaltarget在自身渲染块内获取委托,纯子节点更新不再拆建监听。

八、语言语义与类型系统的定型

  • 0.3.69:TSRX 元素与裸片段成为默认表达式语法,component关键字与旧包装标签退役;{html ...}{text ...}指令被移除,raw HTML 统一用各目标原生的innerHTML/dangerouslySetInnerHTML,文本用普通{expr}并显式String(value)强转;Ripple 导出类型化Fragment并支持innerHTML展开。
  • 0.3.83@{ … }内的普通 JS 控制流(if/for/while/switch/try)不再被误路由进模板转换,而是像普通function C() { …; return <jsx> }一样编译;客户端与服务端不再发射return_guard簿记变量,提前return就是真正的提前返回。
  • 0.3.78 / 0.3.76:动态标签语法经历<@...>→ 运行时Dynamic助手 →<{expr}>语法三阶段;最终Dynamic组件 JS 导出被移除,React/Preact 生产产物把动态标签降级为作用域组件别名,Ripple SSR 走内部_$_.dynamic_element助手,仅保留类型声明使 type-only 输出仍可类型检查。
  • 0.3.113Component返回类型放宽为新的Renderable联合,与运行时render_value/render_expression的分派一致——元素可渲染、数组递归展平、null 渲染为空、其余字符串化;Promise、函数、Symbol 仍被拒绝。
  • 0.3.127(当前版本):JSX 组件类型对齐公开的Component类型(组件 props、返回可渲染基元或数组的函数均可作 JSX 标签),HTML 标签 hover 使用DetailedHTMLProps限定,同时保留 Ripple 的属性/事件/ref 类型。

九、升级路径提示

从 changelog 可以提炼出一份破坏性变更清单,升级跨版本时需逐项核对:

  1. 移除#ripple命名空间,改用from 'ripple'的标准 import(0.3.4);
  2. 追踪值get()/set()改为.value访问(0.3.7),直接[0]/[1]访问 tracked/derived 值会抛运行时错误(0.3.66);
  3. ripple/server导出由 snake_case 改 camelCase:createStream/getCss(0.3.93);
  4. 组件内禁止直接await,异步统一走trackAsync()(0.3.13);
  5. 运行时Dynamic组件导出移除,动态标签用<{expr}>(0.3.78);
  6. <children />改为{children}表达式语法(0.3.10);
  7. mount()/hydrate()compat选项移除,兼容集成改由 Vite 插件经ripple.config.ts提供(0.3.11)。

十、结语

packages/ripple/CHANGELOG.md不仅是一份版本清单,它记录了 Ripple 从"单包框架"走向"运行时 + 共享 TSRX 编译层"的完整过程:响应式 API 从命名空间收敛为标准 import 与.value语义,SSR 从静态校验走到流式分块输出,DOM 协调从注释锚点走向锚点最小化,类型系统逐步对齐运行时真实行为。结合 package.json 的 exports 面、src/server/index.js 与 src/runtime/index-server.js 等源码文件,可以逐条把 changelog 中的每个断言落到具体实现上——这也是阅读任何框架 changelog 并据此做升级决策的通用方法。

【免费下载链接】ripplethe elegant TypeScript UI framework项目地址: https://gitcode.com/GitHub_Trending/ripple25/ripple

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询