ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

读懂 Ripple 的构建层:从 @ripple-ts/vite-plugin CHANGELOG 梳理插件演进与实现细节

读懂 Ripple 的构建层:从 @ripple-ts/vite-plugin CHANGELOG 梳理插件演进与实现细节 读懂 Ripple 的构建层从 ripple-ts/vite-plugin CHANGELOG 梳理插件演进与实现细节【免费下载链接】ripplethe elegant TypeScript UI framework项目地址: https://gitcode.com/GitHub_Trending/ripple25/rippleripple-ts/vite-plugin是 Ripplethe elegant TypeScript UI framework接入 Vite 的核心桥梁它负责编译.tsrx组件、注册 dev server 的 SSR/API 中间件、驱动生产构建的客户端/服务端双产物生成并实现流式 SSR、HMR 样式同步等关键体验。本文以 packages/vite-plugin/CHANGELOG.md 为主线完整梳理该插件从0.2.x到当前0.3.127的版本演进把 changelog 中每一条实质性变更记录.tsrx工具链支持、dep-scan 修复、流式 SSR、全局 root boundary、源码图串联等与 packages/vite-plugin/src/index.js、packages/vite-plugin/src/load-config.js 等源码实现相互印证帮助读者既掌握插件的当前配置面也理解每项能力背后的调用链与修复动机。插件在仓库中的定位ripple-ts/vite-plugin位于 monorepo 的 packages/vite-plugin 目录。从 packages/vite-plugin/package.json 可以看到其关键事实当前版本0.3.127与 CHANGELOG 顶部条目一致主入口src/index.js额外导出./production子路径packages/vite-plugin/src/server/production.js供生产环境启动服务端入口运行时依赖为ripple-ts/adapter平台运行时适配与tsrx/rippleTSRX → Ripple 编译器devDependencies 中的vite说明插件随 Vite 8 一起工作见后文0.3.4的 Upgrade to Vite 8 记录。插件入口是ripple()函数packages/vite-plugin/src/index.js#L339 中它返回一个插件数组——首元素是name: vite-plugin-ripple、enforce: pre的主插件resolver 先于 Vite 内部 resolver 运行其余为辅助插件。ripple()接受一个可选项excludeRippleExternalModules类型定义见 packages/vite-plugin/types/index.d.ts#L106-L108设为true时跳过对node_modules中 Ripple 源码包的扫描直接进入optimizeDeps.exclude合并逻辑见 packages/vite-plugin/src/index.js#L493-L502。CHANGELOG 中绝大多数条目形如 Updated dependencies只列出tsrx/ripple与ripple-ts/adapter的联动版本号——这是因为 monorepo 内工作区包workspace:*随 changesets 一起同步发版vite-plugin 本体往往没有改动。真正承载技术信息的是下文逐一解读的十余条功能性条目。版本号演进一次 1.0 回退与持续的 0.3.xCHANGELOG 记录了一条有趣的版本弧线0.3.4之前是0.3.00.3.30.3.4升级 Vite 8#807。0.2.2090.2.216段与0.3.x段在文件中交错出现如0.2.214出现在0.3.0之后见 CHANGELOG L1281-L1305其中0.2.214的备注是 Force patch version bump for vite-plugin package属于人为补发的版本号。1.0.0/1.0.1曾在0.3.25与0.3.26之间发布CHANGELOG L1041-L1056。随后0.3.51明确说明原因Patch packages currently versioned at 0.3.50 to fix the bump that caused major 1.0.0 release with a minor changeset.即一次 minor changeset 被错误地算成了 major 跳版团队用0.3.51修正并回到0.3.x轨道此后至0.3.127一直保持 patch 递增。这说明当前0.3.x并非未到 1.0而是版本治理修正后的延续序列引用该插件时应以 packages/vite-plugin/package.json 中的version字段为准。关键演进节点逐条解读功能性变更以下按时间顺序覆盖 CHANGELOG 中所有带实质描述的条目每条均给出源码佐证。1. SSR dev 期的非法 HTML 嵌套检测0.2.209CHANGELOG L1315-L1335 记录了最早的实质性条目SSR 期间若产出不合法嵌套例如button里再嵌button浏览器会自动修复 DOM导致 hydration 失败且错误难以定位。该修复包含四点服务端运行时新增push_element/pop_element用元素栈追踪当前嵌套状态按 HTML 规范加入完整的嵌套校验规则服务端编译器在dev选项开启时自动发出push_element/pop_element调用CompileOptions新增dev字段Vite 插件在vite devserve 命令时自动打开 dev 模式。最后一点在当前源码中依然成立transformhook 以config?.command serve判定is_dev并把dev: is_dev传给tsrx/ripple的compile()packages/vite-plugin/src/index.js#L1180-L1185。也就是说dev 构建产物里天然带着嵌套校验的运行时探针而vite build产物则不带零生产开销。2. 全工具链.tsrx支持0.3.12 / 0.3.130.3.12CHANGELOG L1160-L1171Add first-phase.tsrxsupport across the core Ripple tooling so Vite, Rollup, TypeScript, the language server, Prettier, ESLint, and editor integrations accept.tsrx文件——插件从此以.tsrx为唯一扩展名参与编译0.3.13将其补全到 Ripple 工具链其余部分并把仓库内受跟踪的模块统一改名为.tsrx。当前源码中这一设定是硬编码的RIPPLE_EXTENSIONS [.tsrx]、RIPPLE_EXTENSION_PATTERN /\.tsrx$/packages/vite-plugin/src/index.js#L51-L52transformhook 的filter即基于该正则L1174。3. 修复 SSR/API 中间件注册时机0.3.35PR #966这是理解 dev server 请求路径的关键条目CHANGELOG L936-L958问题configureServerhook 此前返回了一个函数post-hook使 Ripple 的中间件注册在 Vite 内部中间件之后Vite 的 HTML fallback 中间件会先截走所有非文件 GET 请求导致 SSR 渲染与 API 路由永远没有机会执行。修复改为pre-hook函数不返回值直接vite.middlewares.use(...)并把配置加载延迟到首个请求由ensureConfigLoaded()负责——配置缺失时重试、加载错误以 dev server 的 500 页面呈现而不是静默穿透。当前实现完整保留了这一结构configureServerpackages/vite-plugin/src/index.js#L586-L797不返回函数注释明确写道 Pre-hook: register middleware directly without returning a function, so it is inserted BEFORE Vites built-in stackensureConfigLoaded()的完整逻辑缺失不缓存、失败后仅在文件 mtime 变化时重试在 L604-L673。此外加载失败时插件选择next()放行而非返回 500保证一个坏掉的ripple.config.ts不会拖垮 HMR、CSS、模块请求等 Vite 内部功能L683-L696。配套的 packages/vite-plugin/tests/configure-server.test.js 对该 hook 行为有专门测试。4. RenderRoute 的 params 传入 SSR 组件0.3.36PR #999条目CHANGELOG L923-L934很短但意义重大路由匹配出的params从此会传给 SSR 编译后的页面组件。dev 中间件中的实现是createContext(request, freshMatch.params)packages/vite-plugin/src/index.js#L746-L747Context类型的params: Recordstring, string定义在 packages/vite-plugin/types/index.d.ts#L87-L96并有 packages/vite-plugin/tests/render-route-props.test.js 覆盖。5. 源码图串联到 Vite JSX transform0.3.62PR #1148Chain TSRX compiler source maps through the Vite JSX transform so browser devtools show original.tsrxsources instead of generated TSXCHANGELOG L684-L695。此前 devtools 里看到的是编译中间产物修复后断点与组件树都映射回.tsrx源文件。对应的测试是 packages/vite-plugin/tests/transform-source-maps.test.js。transformhook 返回{ code, map }的形态packages/vite-plugin/src/index.js#L1198保证了 map 始终向上传递。6. 全局 root boundary、命名导出入口与代码生成重构0.3.66PR #1168这条CHANGELOG L638-L655包含三项全局 root pending/catch boundaryripple.config.ts顶层可配rootBoundary: { pending, catch }。当前类型定义在 packages/vite-plugin/types/index.d.ts#L114-L117, L142-L143resolveRippleConfig会校验其必须是组件函数并默认{}packages/vite-plugin/src/load-config.js#L58-L76, L142配置路由可引用命名导出RenderRoute的entry从纯路径字符串扩展为string | readonly [exportName: string, path: string]元组packages/vite-plugin/types/index.d.ts#L112。解析工具get_route_entry_path/get_route_entry_export_name/get_component_export都在 packages/vite-plugin/src/routes.js#L16-L56——找不到指定命名导出时依次回退到default导出、第一个大写开头的函数导出代码生成集中化Refactor vite-plugin to keep code generation in one place, produce cache as necessary and generate actual files for inspection。这对应 packages/vite-plugin/src/project-codegen.js 中的write_project_generated_file虚拟模块如virtual:ripple-hydrate的客户端入口现在会写成真实文件落盘方便排查——见loadhook 中先write_project_generated_file(..., client-entry.js, ...)再读回的流程packages/vite-plugin/src/index.js#L1156-L1166测试在 packages/vite-plugin/tests/project-codegen.test.js。7. 客户端 hydration 组合 RenderRoute 布局0.3.82修复了一个典型的服务端有、客户端无的布局丢失 bugCHANGELOG L459-L476此前生成的客户端入口只 hydrate 裸页面组件路由的layout只存在于服务端 HTML——布局组件从未在浏览器执行其 CSS 也不在客户端依赖图里hydration 后 SSR 样式块被移除布局样式随之消失表现为无样式闪烁 FOUC。修复方式是客户端入口加载 layout 模块并以与服务端相同的方式包裹页面且 layout 条目进入客户端构建的静态路由导入清单确保其 CSS 被打进 bundle。当前buildStarthook 正是这一修复的载体收集 render 路由时同时 flatMap[get_route_entry_path(r.entry), r.layout]并去重packages/vite-plugin/src/index.js#L559-L569RenderRoute类也带有layout字段packages/vite-plugin/src/routes.js#L72。8. 流式 SSR0.3.92PR #1326——插件侧最重要的能力跃迁CHANGELOG L349-L370 的完整描述值得逐句拆解render(App, { stream })变为渐进式流同步壳含挂起的try边界 pending 回退与当前已注册的全部 CSS立即 flush各边界内容在其异步工作完成后作为带帧framed的乱序块流出包含每块 CSS、trackAsync信封与head内容一小段内联 runtime 在 hydration 前把块替换进对应槽位hydration 后的边界就地激活流式块——直接认领已流出的 DOM不重新渲染catch-only 边界先流空槽位最终解析为 body 或服务端渲染的 catchcatch 区已在线的错误的处理经 error 信封交给客户端边界render新增streamTemplate选项用于文档骨架vite plugin 在ripple.config.ts中开启ssr.streaming时对 render 路由响应做流式输出若index.html缺少!--ssr-head--/!--ssr-body--标记则回退到缓冲式 SSR。源码侧可以逐一印证配置面ssr.streaming默认false其 JSDoc 明确写了标记要求与回退策略packages/vite-plugin/types/index.d.ts#L144-L156resolveRippleConfig落默认值在 packages/vite-plugin/src/load-config.js#L143-L145标记解析buildStreamTemplate()按!--ssr-head--/!--ssr-body--把模板切成before/between/after三段缺标记时返回null供调用方回退packages/vite-plugin/src/server/stream-response.js#L10-L38响应组装createStreamingResponse()启动render(component, { stream: sink, rootBoundary, streamTemplate })并立即返回Response(stream)渲染 Promise 的异常直接打到 sink 上packages/vite-plugin/src/server/stream-response.js#L54-L78。该 helper 被 dev serverpackages/vite-plugin/src/server/render-route.js与生产 runtimepackages/vite-plugin/src/server/production.js共享注释中写明其平台无关性测试packages/vite-plugin/tests/stream-response.test.js。9.ripple/server助手导出的 camelCase 重命名0.3.93create_ssr_stream→createStreamget_css_for_hashes→getCss返回render()收集的 scoped style hash 对应的 CSS 文本旧 snake_case 导出被移除需要更新 import。CHANGELOG 同时说明 The vite plugin consumes the new names internallyCHANGELOG L327-L347——这解释了createStreamingResponse的入参里出现createSsrStream的依赖注入形态packages/vite-plugin/src/server/stream-response.js#L45-L51插件本身不硬依赖运行时命名而是由调用方注入保持平台无关。这是一条破坏性变更升级时需要迁移ripple/server的 import。10. HMR 更新导致组件样式消失的修复0.3.6PR #819这是一个高频痛点编辑组件 scoped CSS 时 CSS hash 会变但虚拟 CSS 模块既未被失效也未被包含进 HMR 更新浏览器持有旧 selector与新 hash 的 class 名失配全部样式消失直到重启 dev serverCHANGELOG L1208-L1228。当前hotUpdatehandlerpackages/vite-plugin/src/index.js#L814-L870实现了修复并演进了一步注释说明借鉴了 vite-plugin-svelte 的思路——不在hotUpdate里手动重编译而是调用this.environment.transformRequest(filename)跑完整 Vite 管线load → transform由既有transformhook 重编译并更新cssCache顺带避免了双重编译随后比对前后cssCache若 CSS 变化则invalidateModule虚拟 CSS 模块并将其加入 HMR 更新列表保证浏览器拿到的新 CSS 与重渲染组件同步。对非 Ripple 文件若模块不自接受则失效 SSR 模块图并发送full-reload。11. 移除 TSX island 与 React bridge0.3.73PR #1198Remove the unused namespaced TSX island feature and React bridge packageCHANGELOG L568-L581未使用的功能面被裁掉插件从此只聚焦.tsrx单一源码形态。12. 升级到 Vite 8 与类型拆分0.3.4PR #807Upgrade to Vite 8CHANGELOG L1237-L1251。同一条版本里还有一个工程细节把生产子路径./production的类型声明拆到独立文件 packages/vite-plugin/types/production.d.ts让导出类型无需 self-import 技巧即可干净解析。13. dep-scan 让.tsrx导入对依赖预打包可见0.3.113PR #1394这条CHANGELOG L144-L184是插件在 dev 性能上的关键修复信息密度很高根因Vite 的 dep scanner 走 Rolldown 且不经过主插件管线因此只从.tsrx文件 import 的 npm 依赖在启动扫描阶段不可见只能在请求时才被发现触发 re-optimize 和整页重载方案tsrx/core新增tsrx/core/vite/dep-scan入口提供两种插件形态——直接 transform.tsrxid 的createDepScanTransformPlugin以及把 id 改写为虚拟path.tsx形态的createDepScanLoadPlugin两者都吞掉编译失败单个坏文件不再拖垮整个项目的依赖预打包附带修复扫描自身的 JSX transform 默认 React automatic runtime会往 Preact/Solid/Vue 项目里发射无法解析的react/jsx-dev-runtimeimport 导致扫描整体失败React/Preact 插件改为指向配置的 import sourceSolid/Vue 插件在扫描期保持 JSX 不转换。Ripple 插件侧的实现是dep_scan_configpackages/vite-plugin/src/index.js#L378-L402extensions: [.tsrx]注释解释了为什么必须声明——scanner 对外部扩展名一律 externalize并在rolldownOptions.plugins挂入createDepScanTransformPlugincompile回调使用compile(code, id, { mode: client, dev: true, hmr: false })moduleType: js。该配置对象被展开进confighook 返回的每个optimizeDeps中L496-L535。packages/vite-plugin/tests/dep-scan.test.js 有四组断言精确锁定上述行为扩展名与 filter 只匹配.tsrxL25-L33、保留已有 exclude 列表L35-L39、扫描期编译产物保持from some-dep且moduleType为jsL41-L56、编译失败返回空模块{ code: , moduleType: js }而非抛错L58-L69。14. 消费已发布的共享 TSRX 包0.3.125PR #1437最近的实质性条目CHANGELOG L21-L34TSRX 目标无关源码迁移到独立仓库tsrx-org/tsrx后Ripple 不再内嵌编译器/工具链改为消费其发布包新 Ripple 项目使用tsrx/language-server、TSRX editor identity 与已发布的 TSRX 集成。对应地插件对编译器的依赖收敛为 packages/vite-plugin/src/index.js#L7 的import { compile } from tsrx/ripple与 L8 的import { createDepScanTransformPlugin } from tsrx/core/vite/dep-scan。当前配置面总览ripple.config.ts上述演进累积出了当前的配置结构。RippleConfigOptions定义于 packages/vite-plugin/types/index.d.ts#L119-L175默认值由resolveRippleConfig统一施加packages/vite-plugin/src/load-config.js#L91-L154该函数被声明为幂等且是所有配置校验与默认值的唯一事实来源字段类型/默认值说明build.outDir默认dist生产构建输出目录客户端产物在outDir/client服务端产物在outDir/serverbuild.minify默认undefined客户端走 Vite 默认 esbuild仅当显式设置时覆盖minify见 packages/vite-plugin/src/index.js#L480-L484build.target默认undefined传递给 SSR 子构建adapter开发期可选生产构建必填requireAdapter: true含serve与runtime生产构建缺 adapter 会直接抛错packages/vite-plugin/src/load-config.js#L103-L117router.routes默认[]RenderRoute/ServerRoute实例数组packages/vite-plugin/src/routes.js#L61-L124无路由时插件退化为纯 SPA 插件rootBoundary默认{}全局 pending/catch UI客户端与 SSR 渲染根共用ssr.streaming默认false开启后 render 路由走流式 SSRindex.html需含!--ssr-head--/!--ssr-body--标记否则自动回退缓冲式middlewares默认[]全局中间件先于路由级before/after执行platform.env默认{}注入平台环境变量server.trustProxy默认false信任X-Forwarded-Proto/X-Forwarded-Host仅置于可信反向代理之后时开启packages/vite-plugin/types/index.d.ts#L162-L174配置加载有两条路径packages/vite-plugin/src/load-config.js#L197-L244dev 期传入运行中的 Vite server走ssrLoadModule直接加载无临时 server 开销、支持 HMR 感知重载build/preview 期则临时创建 middleware 模式的 Vite server 转译ripple.config.ts后立即关闭。ripple.config.ts路径固定为root/ripple.config.tsgetRippleConfigPath。仓库内的真实示例可参考 playground/ripple/ripple.config.ts 与 website-new/ripple.config.ts。生产构建的完整链路closeBundlehookpackages/vite-plugin/src/index.js#L891-L1099是 changelog 多次演进代码生成集中化、布局进客户端图、manifest 资产映射汇聚后的产物值得作为整体了解读取客户端构建的.vite/manifest.json按路由 entry 递归收集 JS/CSScollectCss带 visited 集合防环构建 per-route 的clientAssetMap清理dist/client/.vite避免静态服务器把源文件路径暴露给用户由 packages/vite-plugin/src/server/virtual-entry.js 的generateServerEntry生成服务端入口含路由表、client 资产映射、RPC 模块路径经write_project_generated_file落盘为server-entry.js再调一次viteBuild做 SSR 子构建ssr: true、输出 ESM 到outDir/serverripple-ts/adapter*系列全部 external把index.html模板复制进 server 输出使服务端入口自包含——注释特别说明这对dist/client 被当纯静态文件服务的平台如 Vercel至关重要。客户端侧buildStart预加载 render 路由条目transformIndexHtml在/body前注入script typemodule srcvirtual:ripple-hydratepackages/vite-plugin/src/index.js#L876-L885virtual:ripple-hydrate由loadhook 生成客户端入口源码packages/vite-plugin/src/project-codegen.js 的create_client_entry_source。如何验证与继续阅读插件行为测试packages/vite-plugin/tests 下六个文件——dep-scan.test.js预打包扫描、configure-server.test.jsdev server 中间件顺序与懒加载、render-route-props.test.jsparams 传递、stream-response.test.js流式模板切分与回退、transform-source-maps.test.js源码图、project-codegen.test.js生成文件完整类型契约packages/vite-plugin/types/index.d.ts含RipplePluginOptions、RippleConfigOptions、ResolvedRippleConfig可运行的项目形态playground/ripple含ripple.config.ts与vite.config.js的完整组合、website-new以 Ripple 构建的站点本身与 templates/basic项目模板。综上这份 CHANGELOG 记录的不仅是一串版本号它完整呈现了 Ripple 构建层的四条主线——.tsrx工具链集成、dev server 请求路径与中间件秩序、构建期代码生成与双产物管线、SSR 能力从能渲染到可流式、可追踪、可调试的成熟过程——而每一处源码现状都能在这些条目中找到动机与出处。【免费下载链接】ripplethe elegant TypeScript UI framework项目地址: https://gitcode.com/GitHub_Trending/ripple25/ripple创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表