Svelte 为什么没有 core 特判

先说明结论

当前仓库中,Svelte 支持主要存在于 create-rslib 模板层,而不是 packages/core 的特殊逻辑里。Core 没有类似 Vue 的 rspack-vue-loader 特判,也没有针对 svelte-loader 的 bundleless external 例外。

这不表示 Svelte 不需要编译,而是说明当前 Svelte loader 输出没有在 Rslib core 中暴露出必须特殊处理的模块图冲突。

Svelte 模板做了什么

Svelte TS 模板配置大致是:

import { pluginSvelte } from '@rsbuild/plugin-svelte';
import { defineConfig } from '@rslib/core';
import { svelteDtsPlugin } from './scripts/rslib-plugin-svelte-dts';

export default defineConfig({
  lib: [
    {
      format: 'esm',
    },
  ],
  output: {
    target: 'web',
  },
  plugins: [pluginSvelte(), svelteDtsPlugin()],
});

也就是说:

  • Svelte 编译由 @rsbuild/plugin-svelte 处理。
  • Svelte TS 声明文件由模板内 svelte2tsx 插件处理。
  • core 没有写 Svelte-specific branch。

和 Vue 的差异

Vue 的问题出现在 bundleless external 的拦截点。rspack-vue-loader 会生成类似:

rspack-vue-loader/dist/exportHelper.js
Button.vue?vue&type=script
Button.vue?vue&type=template

这些 request 如果被当作普通源码 import 保留,会泄露 loader 内部结构。

当前 Svelte 模板和测试没有出现类似:

svelte-loader/dist/helper.js
Button.svelte?svelte&type=...

进入 core bundleless external 并需要特殊放行的情况。

另一个现实原因:模板默认不是 bundleless

Svelte 模板默认只是:

lib: [{ format: 'esm' }];

没有 bundle: false。这意味着它默认走 bundle 模式,而不是触发 Rslib 最复杂的 bundleless external 路径。

Vue 相关测试明确覆盖了 bundleless Vue 组件库,因此更容易暴露 loader 虚拟请求和 bundleless external 的冲突。

如果未来 Svelte 需要特判

如果未来出现 Svelte bundleless 产物泄露 loader 内部 request,应按 Vue 的标准判断是否需要特判:

  1. request 是否来自 loader 内部,而不是用户源码公共 import。
  2. request 是否进入 composeBundlelessExternalConfig
  3. 如果保留到产物中,消费者是否无法解析。
  4. 是否能用更通用的 outBase 或 external 规则解决。
  5. 是否有最小 fixture 能复现。

只有这些条件都满足,才应考虑新增 Svelte-specific hack。

不应该做什么

不要因为 Svelte 是框架,就提前在 core 中加宽泛规则,例如:

request.includes('svelte');

这会误伤正常 import:

import { mount } from 'svelte';

或者:

import Button from './Button.svelte';

框架 hack 必须绑定具体 loader 内部 request,而不是框架包名。

测试建议

如果将来要验证 Svelte bundleless,应添加集成测试覆盖:

  • bundle: false
  • .svelte entry。
  • 嵌套 .svelte import。
  • style 输出。
  • package external。
  • dts 输出。
  • 产物中不包含 loader 内部 request。

只有看到真实失败形态,才值得把规则加到 core。