框架适配总览:React、Vue、Svelte 与通用规则
先区分 core 和模板
讨论 Rslib 对框架的支持时,要先区分两层:
很多“Rslib 支持 React/Vue/Svelte”的能力其实在模板层。例如 React 模板使用 @rsbuild/plugin-react,Vue 模板使用 @rsbuild/plugin-vue,Svelte 模板使用 @rsbuild/plugin-svelte。这些不等于 core 里有框架 hack。
Core 里真正值得注意的是那些为了库产物正确性而写的特殊分支。
总览表
Vue:为什么是明确 hack
Vue SFC loader 会生成内部 request,例如:
这些 request 出现在 Rspack 模块图里,会经过 bundleless external 的拦截点。Rslib 不能把它们当普通源码 import 保留到产物中,因为消费者不应该看到 rspack-vue-loader 的内部实现。
所以 core 中专门识别 rspack-vue-loader,对 dist/exportHelper.js 和 ?vue&type= 放行,让 Rspack 正常 bundle 这些内部模块。
这是明确的 Vue-specific hack。
React:主要是 JSX 和 SVGR
React 相关的 core 逻辑不是“看到 React 就特殊处理”,而是围绕 React 生态常见产物形态:
- JSX preserve。
- SVGR。
react/jsx-runtimeexternal。
JSX preserve
React 组件库有时希望保留 JSX 源语法,让下游继续编译。但 Rslib 只允许 bundleless preserve JSX,不允许 bundle preserve JSX。因为 bundle 产物应是可执行 JS bundle,里面保留 JSX 会让运行时不可用。
这不是只服务 React,但实际主要影响 React。
SVGR
SVGR 会把 SVG 转成 React component,但 mixed import 还会同时生成资源 URL。Core 的特殊处理主要是 URL 部分,不是 React component 部分。
Svelte:为什么目前没有 core hack
Svelte 模板通过 @rsbuild/plugin-svelte 接入。TS 模板还有 svelte2tsx dts 插件。当前 core 没有发现需要识别 svelte-loader 内部 request 的逻辑。
这里不是说 Svelte 永远不需要 hack,而是当前仓库的实现和测试没有暴露类似 Vue 的问题。Svelte loader 输出的模块图没有以同样方式把 loader 内部 block request 泄露到 bundleless external 重写流程里。
另一个现实原因是:Rslib 的 Svelte 模板默认不是 bundleless。它配置的是普通 ESM bundle。这也减少了触发 bundleless external 冲突的机会。
通用规则覆盖了很多框架需求
很多框架组件库需求并不是框架特判,而是通用库构建能力:
- peer dependency external。
- CSS extract。
- CSS Modules。
- asset emit。
- bundleless source structure。
- dts 输出。
- target web。
例如 React 和 Vue 都需要 CSS 被正确抽取,Svelte 也可能需要 CSS 输出;这不需要分别写 React/Vue/Svelte 三套逻辑,而是 CSS 子系统统一处理。
判断是否需要新增框架 hack
新增框架 hack 应该非常谨慎。只有满足下面条件时才考虑:
- loader 产生的内部 request 会进入 Rslib bundleless external 或 asset 规则。
- 这些 request 如果保留到产物中,会让消费者依赖 loader 内部实现。
- 通用规则无法区分它和用户源码 import。
- 有最小复现和 integration test。
- 特判范围足够窄,不会误伤用户正常 import。
Vue 的 rspack-vue-loader 特判满足这些条件。Svelte 当前没有。
修改风险
框架 hack 的风险在于它很容易绑定 loader 内部实现。loader 升级后 request 字符串可能变化,Rslib 的判断就会失效。
因此这类逻辑应:
- 写在离冲突机制最近的地方。
- 用清楚注释说明为什么存在。
- 有真实框架 fixture 测试。
- 尽量匹配具体 loader 包名和具体 request pattern。
- 不要用过宽的规则,例如只要 request 包含
vue就放行。