Docs
Storybook Docs

适用于 SvelteKit 的 Storybook

Storybook for SvelteKit 是一个 framework,它可以轻松地为使用 构建的 SvelteKit 应用单独开发和测试 UI 组件。它包括:

¥Storybook for SvelteKit is a framework that makes it easy to develop and test UI components in isolation for SvelteKit applications. It includes:

  • 🪄 零配置

    ¥🪄 Zero config

  • 🧩 轻松模拟多个 Kit 模块

    ¥🧩 Easily mock many Kit modules

  • 🔗 自动链接处理

    ¥🔗 Automatic link handling

  • 💫 还有更多!

    ¥💫 and more!

要求

¥Requirements

  • SvelteKit ≥ 1.0

  • Storybook ≥ 8.0

入门

¥Getting started

在没有 Storybook 的项目中

¥In a project without Storybook

在 Sveltekit 项目的根目录中运行此命令后,按照提示进行操作:

¥Follow the prompts after running this command in your Sveltekit project's root directory:

npm create storybook@latest

有关开始使用 Storybook 的更多信息。

¥More on getting started with Storybook.

在带有 Storybook 的项目中

¥In a project with Storybook

此框架旨在与 Storybook 7+ 配合使用。如果你尚未使用 v7,请使用以下命令升级:

¥This framework is designed to work with Storybook 7+. If you’re not already using v7, upgrade with this command:

npx storybook@latest upgrade

自动迁移

¥Automatic migration

运行上面的 upgrade 命令时,你应该会收到一个提示,要求你迁移到 @storybook/sveltekit,它应该为你处理所有事情。如果自动迁移不适用于你的项目,请参考下面的手动迁移。

¥When running the upgrade command above, you should get a prompt asking you to migrate to @storybook/sveltekit, which should handle everything for you. In case that auto-migration does not work for your project, refer to the manual migration below.

手动迁移

¥Manual migration

首先,安装框架:

¥First, install the framework:

This snippet doesn't exist for react.
npm install --save-dev @storybook/sveltekit

然后,更新你的 .storybook/main.js|ts 以更改框架属性:

¥Then, update your .storybook/main.js|ts to change the framework property:

.storybook/main.js
This snippet doesn't exist for react.
export default {
  // ...
  framework: '@storybook/sveltekit', // 👈 Add this
  // svelteOptions: { ... }, 👈 Remove this
};

最后,这些包现在要么已经过时,要么是 @storybook/sveltekit 的一部分,因此你不再需要直接依赖它们。你可以从项目中删除它们(npm uninstallyarn removepnpm remove):

¥Finally, these packages are now either obsolete or part of @storybook/sveltekit, so you no longer need to depend on them directly. You can remove them (npm uninstall, yarn remove, pnpm remove) from your project:

  • @storybook/svelte-vite

  • @storybook/svelte-webpack5

  • storybook-builder-vite

  • @storybook/builder-vite

支持的功能

¥Supported features

所有 Svelte 语言功能均开箱即用,因为 Storybook 框架直接使用 Svelte 编译器。但是,SvelteKit 有一些不受支持的 Kit 特定模块。以下是 Storybook 中有效和无效功能的细分:

¥All Svelte language features are supported out of the box, as the Storybook framework uses the Svelte compiler directly. However, SvelteKit has some Kit-specific modules that aren't supported. Here's a breakdown of what will and will not work within Storybook:

模块状态注意
$app/environment✅ 支持version 在 Storybook 中始终为空。
$app/forms⚠️ 实验性参见 如何模拟
$app/navigation⚠️ 实验性参见 如何模拟
$app/paths✅ 支持需要 SvelteKit 1.4.0 或更新版本。
$app/stores⚠️ 实验性参见 如何模拟
$env/dynamic/public🚧 部分支持仅在开发模式下受支持。Storybook 是作为静态应用构建的,没有服务器端 API,因此无法动态提供内容。
$env/static/public✅ 支持
$lib✅ 支持
@sveltejs/kit/*✅ 支持
$env/dynamic/private⛔ 不支持这是一个服务器端功能,Storybook 在客户端上渲染所有组件。
$env/static/private⛔ 不支持这是一个服务器端功能,Storybook 在客户端上渲染所有组件。
$service-worker⛔ 不支持这是一个服务工作者功能,不适用于 Storybook。

如何模拟

¥How to mock

要模拟 SvelteKit 导入,你可以在 parameters.sveltekit_experimental 中定义它:

¥To mock a SvelteKit import you can define it within parameters.sveltekit_experimental:

MyComponent.stories.js|ts
export const MyStory = {
  parameters: {
    sveltekit_experimental: {
      stores: {
        page: {
          data: {
            test: 'passed',
          },
        },
        navigating: {
          route: {
            id: '/storybook',
          },
        },
        updated: true,
      },
    },
  },
};

可用参数 在下面 API 部分中有记录。

¥The available parameters are documented in the API section, below.

模拟链接

¥Mocking links

默认的链接处理行为(例如,点击 <a href="..." /> 元素时)是将操作记录到 操作面板

¥The default link-handling behavior (e.g., when clicking an <a href="..." /> element) is to log an action to the Actions panel.

你可以通过将对象分配给 parameters.sveltekit_experimental.hrefs 来覆盖此设置,其中键是表示 href 的字符串,值定义你的模拟。例如:

¥You can override this by assigning an object to parameters.sveltekit_experimental.hrefs, where the keys are strings representing an href, and the values define your mock. For example:

MyComponent.stories.js|ts
export const MyStory = {
  parameters: {
    sveltekit_experimental: {
      hrefs: {
        '/basic-href': (to, event) => {
          console.log(to, event);
        },
        '/root.*': {
          callback: (to, event) => {
            console.log(to, event);
          },
          asRegex: true,
        },
      },
    },
  },
};

有关更多信息,请参阅 API 参考

¥See the API reference for more information.

编写原生 Svelte 故事

¥Writing native Svelte stories

Storybook 提供了由社区维护的 Svelte addon,使你可以使用模板语法为 Svelte 组件编写故事。

¥Storybook provides a Svelte addon maintained by the community, enabling you to write stories for your Svelte components using the template syntax.

社区积极维护 Svelte CSF 插件,但仍然缺少官方 Storybook Svelte 框架支持中目前可用的一些功能。有关更多信息,请参阅 插件文档

¥The community actively maintains the Svelte CSF addon but still lacks some features currently available in the official Storybook Svelte framework support. For more information, see the addon's documentation.

设置

¥Setup

如果你使用 Sveltekit 框架初始化项目,则该插件已为你安装并配置完毕。但是,如果你是从以前版本安装的 migrating,则需要执行其他步骤来启用此功能。

¥If you initialized your project with the Sveltekit framework, the addon has already been installed and configured for you. However, if you're migrating from a previous version, you'll need to take additional steps to enable this feature.

运行以下命令来安装插件。

¥Run the following command to install the addon.

This snippet doesn't exist for react.
npx storybook@latest add @storybook/addon-svelte-csf

CLI 的 add 命令可以自动补齐插件的安装和设置。要手动安装,请参阅我们的 documentation 了解如何安装插件。

¥The CLI's add command automates the addon's installation and setup. To install it manually, see our documentation on how to install addons.

更新你的 Storybook 配置文件(即 .storybook/main.js|ts)以启用对此格式的支持。

¥Update your Storybook configuration file (i.e., .storybook/main.js|ts) to enable support for this format.

.storybook/main.js
This snippet doesn't exist for react.
export default {
  stories: ['../src/**/*.stories.@(js|jsx|ts|tsx|svelte)'],
  addons: [
    // Other Storybook addons
    '@storybook/addon-svelte-csf',
  ],
};

配置

¥Configure

默认情况下,Svelte addon 插件为 Storybook 的 SvelteKit 框架提供零配置支持。但是,你可以扩展 Storybook 配置文件(即 .storybook/main.js|ts)并提供其他插件选项。下面列出了可用的选项及其使用方法示例。

¥By default, the Svelte addon addon offers zero-config support for Storybook's SvelteKit framework. However, you can extend your Storybook configuration file (i.e., .storybook/main.js|ts) and provide additional addon options. Listed below are the available options and examples of how to use them.

.storybook/main.js
This snippet doesn't exist for react.
export default {
  // Other configuration
  addons: [
    {
      name: '@storybook/addon-svelte-csf',
      options: {
        legacyTemplate: true, // Enables the legacy template syntax
      },
    },
  ],
};
选项描述
legacyTemplate启用对 Template 组件的支持以实现向后兼容。
options: { legacyTemplate: true }

启用 legacyTemplate 选项可能会带来性能开销,应谨慎使用。有关更多信息,请参阅 插件文档

¥Enabling the legacyTemplate option can introduce a performance overhead and should be used cautiously. For more information, refer to the addon's documentation.

升级到 Svelte CSF 插件 v5

¥Upgrade to Svelte CSF addon v5

随着 Svelte 5 的发布,Storybook 的 Svelte CSF 插件已更新以支持新功能。本指南将帮助你迁移到最新版本的插件。以下概述了 5.0 版本的主要变化以及升级项目所需的步骤。

¥With the Svelte 5 release, Storybook's Svelte CSF addon has been updated to support the new features. This guide will help you migrate to the latest version of the addon. Below is an overview of the major changes in version 5.0 and the steps needed to upgrade your project.

简化的故事 API

¥Simplified story API

如果你使用 Meta 组件或 meta 命名导出来定义故事的元数据(例如 参数),则需要更新故事以使用新的 defineMeta 函数。此函数返回一个包含所需信息的对象,其中包括你必须用来定义组件故事的 Story 组件。

¥If you are using the Meta component or the meta named export to define the story's metadata (e.g., parameters), you'll need to update your stories to use the new defineMeta function. This function returns an object with the required information, including a Story component that you must use to define your component stories.

MyComponent.stories.svelte
This snippet doesn't exist for react.
<script>
  import { Meta, Story } from '@storybook/addon-svelte-csf';
 
  import MyComponent from './MyComponent.svelte';
</script>
 
 
<Meta title="MyComponent" component={MyComponent} />
 
<Story name="Default" />

Story 模板

¥Story templates

如果你使用 Template 组件来控制组件在 Storybook 中的渲染方式,则此功能已被 Story 组件中的内置子组件支持所取代,使你能够直接在故事中组合组件并定义 UI 结构。

¥If you used the Template component to control how the component renders in the Storybook, this feature was replaced with built-in children support in the Story component, enabling you to compose components and define the UI structure directly in the story.

MyComponent.stories.svelte
This snippet doesn't exist for react.
<script>
  import { Meta, Template, Story } from '@storybook/addon-svelte-csf';
 
  import OuterComponent from './OuterComponent.svelte';
  import MyComponent from './MyComponent.svelte';
</script>
 
<Meta title="MyComponent" component={MyComponent} />
 
<Template let:args>
  <OuterComponent>
    <MyComponent />
  </OuterComponent>
</Template>
 
<Story name="Default" />

如果你需要支持 Template 组件,该插件提供了一个功能标志以实现向后兼容。有关更多信息,请参阅 配置选项

¥If you need support for the Template component, the addon provides a feature flag for backward compatibility. For more information, see the configuration options.

故事片段插槽

¥Story slots to snippets

随着 Svelte 插槽的弃用和可复用 snippets 的引入,该插件也引入了对此功能的支持,允许你扩展 Story 组件并提供自定义代码片段,为你的故事提供动态内容。此功能扩展了 Story 组件中内置的 children 支持,使你能够在不损失响应式的情况下创建动态故事。

¥With Svelte's slot deprecation and the introduction of reusable snippets, the addon also introduced support for this feature allowing you to extend the Story component and provide a custom snippet to provide dynamic content to your stories. This feature extends the built-in children support in the Story component, allowing you to create dynamic stories without losing reactivity.

MyComponent.stories.svelte
<script>
  import { defineMeta } from '@storybook/addon-svelte-csf';
 
  import MyComponent from './MyComponent.svelte';
 
  const { Story } = defineMeta({
    component: MyComponent,
  });
</script>
 
<Story name="Default" args={{ exampleProperty: true }}>
  {#snippet children(args)}
    <MyComponent {...args}>Reactive component</MyComponent>
  {/snippet}
</Story>

标签支持

¥Tags support

如果你启用了使用 autodocs 故事属性的自动文档生成功能,则必须将其替换为 tags。此属性允许你根据特定条件对故事进行分类和筛选,并根据应用于故事的标签生成文档。

¥If you enabled automatic documentation generation with the autodocs story property, you must replace it with tags. This property allows you to categorize and filter stories based on specific criteria and generate documentation based on the tags applied to the stories.

MyComponent.stories.svelte
This snippet doesn't exist for react.
<script>
  import { Meta, Template, Story } from '@storybook/addon-svelte-csf';
 
  import MyComponent from './MyComponent.svelte';
</script>
 
<Meta title="MyComponent" component={MyComponent} />
 
<Template let:args>
  <MyComponent {...args} />
</Template>
 
<Story name="Default" autodocs />

API

参数

¥Parameters

此框架在 sveltekit_experimental 命名空间下为 Storybook 贡献了以下 参数

¥This framework contributes the following parameters to Storybook, under the sveltekit_experimental namespace:

forms

类型:{ enhance: () => void }

¥Type: { enhance: () => void }

$app/forms 模块提供模拟。

¥Provides mocks for the $app/forms module.

forms.enhance

类型:() => void

¥Type: () => void

提交带有 use:enhance 的表单时将调用的回调。

¥A callback that will be called when a form with use:enhance is submitted.

hrefs

类型:Record<[path: string], (to: string, event: MouseEvent) => void | { callback: (to: string, event: MouseEvent) => void, asRegex?: boolean }>

¥Type: Record<[path: string], (to: string, event: MouseEvent) => void | { callback: (to: string, event: MouseEvent) => void, asRegex?: boolean }>

如果你的代码中有一个 <a /> 标签,并且 href 属性与定义的一个或多个链接匹配(如果 asRegex 属性是 true,则视为基于正则表达式),则会调用相应的 callback。如果没有定义匹配的 hrefs,则将操作记录到 操作面板。有关示例,请参阅 模拟链接

¥If you have an <a /> tag inside your code with the href attribute that matches one or more of the links defined (treated as regex based if the asRegex property is true) the corresponding callback will be called. If no matching hrefs are defined, an action will be logged to the Actions panel. See Mocking links for an example.

类型:参见 SvelteKit 文档

¥Type: See SvelteKit docs

$app/navigation 模块提供模拟。

¥Provides mocks for the $app/navigation module.

类型:参见 SvelteKit 文档

¥Type: See SvelteKit docs

每当调用 goto 时将调用的回调。如果没有提供函数,则将操作记录到 操作面板

¥A callback that will be called whenever goto is called. If no function is provided, an action will be logged to the Actions panel.

类型:参见 SvelteKit 文档

¥Type: See SvelteKit docs

每当调用 pushState 时将调用的回调。如果没有提供函数,则将操作记录到 操作面板

¥A callback that will be called whenever pushState is called. If no function is provided, an action will be logged to the Actions panel.

类型:参见 SvelteKit 文档

¥Type: See SvelteKit docs

每当调用 replaceState 时将调用的回调。如果没有提供函数,则将操作记录到 操作面板

¥A callback that will be called whenever replaceState is called. If no function is provided, an action will be logged to the Actions panel.

类型:参见 SvelteKit 文档

¥Type: See SvelteKit docs

每当调用 invalidate 时将调用的回调。如果没有提供函数,则将操作记录到 操作面板

¥A callback that will be called whenever invalidate is called. If no function is provided, an action will be logged to the Actions panel.

类型:参见 SvelteKit 文档

¥Type: See SvelteKit docs

每当调用 invalidateAll 时将调用的回调。如果没有提供函数,则将操作记录到 操作面板

¥A callback that will be called whenever invalidateAll is called. If no function is provided, an action will be logged to the Actions panel.

类型:参见 SvelteKit 文档

¥Type: See SvelteKit docs

将传递给 afterNavigate 函数的对象,该函数将在 onMount 事件触发时调用。

¥An object that will be passed to the afterNavigate function, which will be invoked when the onMount event fires.

stores

类型:参见 SvelteKit 文档

¥Type: See SvelteKit docs

$app/stores 模块提供模拟。

¥Provides mocks for the $app/stores module.

stores.navigating

类型:参见 SvelteKit 文档

¥Type: See SvelteKit docs

navigating 商店的部分版本。

¥A partial version of the navigating store.

stores.page

类型:参见 SvelteKit 文档

¥Type: See SvelteKit docs

page 商店的部分版本。

¥A partial version of the page store.

stores.updated

类型:boolean

¥Type: boolean

表示 updated 值的布尔值(你也可以访问 updated.check(),这将是无操作)。

¥A boolean representing the value of updated (you can also access updated.check() which will be a no-op).

选项

¥Options

如果需要,你可以传递一个选项对象以进行其他配置:

¥You can pass an options object for additional configuration if needed:

.storybook/main.js
This snippet doesn't exist for react.
export default {
  // ...
  framework: {
    name: '@storybook/sveltekit',
    options: {
      // ...
    },
  },
};

可用选项包括:

¥The available options are:

builder

类型:Record<string, any>

¥Type: Record<string, any>

配置 框架的构建器 的选项。对于 Sveltekit,可用选项可以在 Vite 构建器文档 中找到。

¥Configure options for the framework's builder. For Sveltekit, available options can be found in the Vite builder docs.

故障排除

¥Troubleshooting

启动 Storybook 时出错

¥Error when starting Storybook

升级到 v7.0 后启动 Storybook 时,可能会退出并出现以下错误:

¥When starting Storybook after upgrading to v7.0, it may quit with the following error:

ERR! SyntaxError: Identifier '__esbuild_register_import_meta_url__' has already been declared

手动从 6.5 升级到 7.0 时可能会发生这种情况。要解决此问题,你需要删除 .storybook/main.js 中的 svelteOptions 属性,因为使用 SvelteKit 的 Storybook 7+ 不支持该属性(并且不再需要该属性)。

¥This can occur when manually upgrading from 6.5 to 7.0. To resolve it, you'll need to remove the svelteOptions property in .storybook/main.js, as that is not supported (and no longer necessary) in Storybook 7+ with SvelteKit.