Skip to content

Svelte 支持

robuild 通过集成 rollup-plugin-svelte 支持构建 Svelte 组件库。这种设置可以编译 .svelte 组件并将其与您的 TypeScript 源码一起打包。

快速开始

安装依赖

sh
pnpm add -D rollup-plugin-svelte svelte svelte-preprocess
sh
npm install -D rollup-plugin-svelte svelte svelte-preprocess
sh
yarn add -D rollup-plugin-svelte svelte svelte-preprocess
sh
bun add -D rollup-plugin-svelte svelte svelte-preprocess

最小配置示例

使用以下 build.config.ts 配置 robuild 以支持 Svelte 库:

build.config.ts
ts
import svelte from 'rollup-plugin-svelte'
import { sveltePreprocess } from 'svelte-preprocess'
import { defineConfig } from 'robuild'

export default defineConfig({
  entry: ['./src/index.ts'],
  platform: 'neutral',
  plugins: [svelte({ preprocess: sveltePreprocess() })],
})

创建你的 Svelte 组件:

Button.svelte
svelte
<script lang="ts">
  export let variant: 'primary' | 'secondary' = 'primary'
  export let disabled: boolean = false
</script>

<button
  class="btn btn-{variant}"
  {disabled}
  on:click
>
  <slot />
</button>

<style>
  .btn {
    padding: 8px 16px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
  }

  .btn-primary {
    background-color: #ff3e00;
    color: white;
  }

  .btn-secondary {
    background-color: #f0f0f0;
    color: #333;
  }

  .btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }
</style>

在入口文件中导出:

index.ts
ts
export { default as Button } from './Button.svelte'

工作原理

  • rollup-plugin-svelte 编译 .svelte 单文件组件。
  • robuild 将编译后的输出与您的 TypeScript 源码一起打包。

INFO

为 Svelte 组件生成 .d.ts 通常需要集成 svelte2tsx。建议使用专门的构建脚本,在打包后使用 svelte2tsx 生成声明文件。

使用 entries 风格配置

如果你喜欢使用 unbuild 风格的 entries 配置:

build.config.ts
ts
import svelte from 'rollup-plugin-svelte'
import { sveltePreprocess } from 'svelte-preprocess'
import { defineConfig } from 'robuild'

export default defineConfig({
  entries: [
    {
      type: 'bundle',
      input: './src/index.ts',
      format: ['esm'],
      platform: 'neutral',
    }
  ],
  plugins: [svelte({ preprocess: sveltePreprocess() })],
  external: ['svelte', 'svelte/internal']
})

外部化 Svelte

构建组件库时,将 svelte 及其内部模块作为外部依赖:

build.config.ts
ts
import svelte from 'rollup-plugin-svelte'
import { sveltePreprocess } from 'svelte-preprocess'
import { defineConfig } from 'robuild'

export default defineConfig({
  entry: ['./src/index.ts'],
  plugins: [svelte({ preprocess: sveltePreprocess() })],
  external: ['svelte', 'svelte/internal'],
})

同时在 package.json 中声明对等依赖:

package.json
json
{
  "peerDependencies": {
    "svelte": "^4.0.0"
  }
}

分发建议

根据社区实践和 SvelteKit 的打包指南避免发布预编译的 JS 组件。建议发布 .svelte 源码,让使用者的 Svelte 工具链(如 Vite + @sveltejs/vite-plugin-svelte)在其应用中编译它们。

不预编译为 JS 的原因

  • 版本兼容性:预编译输出绑定到特定的编译器和 svelte/internal 版本;版本不匹配可能导致运行时或 SSR/水合问题。
  • SSR/水合一致性:库和应用之间不同的编译选项(generatehydratabledev 等)可能导致水合不匹配。
  • 工具和优化:源码形式可从更好的 HMR、诊断、CSS 处理和 tree-shaking 中受益;预编译的 JS 可能失去这些优势。
  • 维护性:Svelte 升级时无需重新发布,因为使用者使用自己选择的版本编译。

适合发布 JS 的情况(例外)

  • 您提供可在 Svelte 外部使用的构件(如 customElement Web Components)。
  • CDN 直接加载场景,无需消费者构建步骤。

TIP

robuild 要点:

  • robuild 中将 svelte/svelte/* 标记为外部依赖,并在 peerDependencies 中声明 svelte
  • 使用 rollup-plugin-svelte 进行预处理/集成,并保持 .svelte 源码形式用于分发。
  • 使用 svelte2tsx 生成与 exports 子路径导出对齐的 .d.ts

发布预编译组件

如果确实需要发布预编译组件(如 Web Components):

build.config.ts
ts
import svelte from 'rollup-plugin-svelte'
import { sveltePreprocess } from 'svelte-preprocess'
import { defineConfig } from 'robuild'

export default defineConfig({
  entry: ['./src/index.ts'],
  plugins: [
    svelte({
      preprocess: sveltePreprocess(),
      compilerOptions: {
        customElement: true, // 生成 Web Components
      },
    }),
  ],
  external: ['svelte'],
})

示例项目

完整示例请参考 playground/svelte-app

下一步

Released under the MIT License.