Storybook for SvelteKit
Storybook for SvelteKit 是一个框架,可轻松地在SvelteKit应用程序中隔离开发和测试 UI 组件。它包括
- 🪄 无需配置
- 🧩 轻松模拟许多 SvelteKit 模块
- 🔗 自动链接处理
- 💫 等等!
要求
- SvelteKit ≥ 1.0
入门
在没有 Storybook 的项目中
在 SvelteKit 项目的根目录中运行此命令后,按照提示操作
npm create storybook@latest在已有 Storybook 的项目中
此框架旨在与 Storybook 7+ 配合使用。如果您尚未升级到 v7,请使用此命令进行升级。
npx storybook@latest upgrade自动迁移
运行上面的 upgrade 命令时,您应该会收到一个提示,要求您迁移到 @storybook/sveltekit,这应该会为您处理所有事情。如果自动迁移不适用于您的项目,请参阅下面的手动迁移。
手动迁移
首先,安装框架。
npm install --save-dev @storybook/sveltekit然后,更新您的 .storybook/main.js|ts 以更改框架属性。
import type { StorybookConfig } from '@storybook/sveltekit';
const config: StorybookConfig = {
// ...
framework: '@storybook/sveltekit', // 👈 Add this
// svelteOptions: { ... }, 👈 Remove this
};
export default config;最后,这些包现在已过时或已成为 @storybook/sveltekit 的一部分,因此您不再需要直接依赖它们。您可以将它们从项目中删除(npm uninstall、yarn remove、pnpm remove)
@storybook/svelte-vitestorybook-builder-vite@storybook/builder-vite
支持的功能
Svelte 语言功能开箱即用,因为 Storybook 框架直接使用 Svelte 编译器。但是,SvelteKit 有一些Kit 特定模块不受支持。以下是 Storybook 中哪些会起作用以及哪些不会起作用的明细
| 模块 | 状态 | 注意 |
|---|---|---|
$app/environment | ✅ 支持 | version 在 Storybook 中始终为空。 |
$app/forms | ⚠️ 实验性 | 请参阅如何模拟。 |
$app/navigation | ⚠️ 实验性 | 请参阅如何模拟。 |
$app/paths | ✅ 支持 | 需要 SvelteKit 1.4.0 或更高版本。 |
$app/state | ⚠️ 实验性 | 需要 SvelteKit v2.12 或更高版本。请参阅如何模拟。 |
$app/stores | ⚠️ 实验性 | 请参阅如何模拟。 |
$env/dynamic/public | 🚧 部分支持 | 仅在开发模式下支持。Storybook 构建为静态应用,没有服务器端 API,因此无法动态提供内容。 |
$env/static/public | ✅ 支持 | |
$lib | ✅ 支持 | |
@sveltejs/kit/* | ✅ 支持 | |
$env/dynamic/private | ⛔ 不支持 | 这是服务器端功能,Storybook 在客户端渲染所有组件。 |
$env/static/private | ⛔ 不支持 | 这是服务器端功能,Storybook 在客户端渲染所有组件。 |
$service-worker | ⛔ 不支持 | 这是服务工作者功能,不适用于 Storybook。 |
如何模拟
要模拟 SvelteKit 导入,您可以在 parameters.sveltekit_experimental 中定义它
export const MyStory = {
parameters: {
sveltekit_experimental: {
state: {
page: {
data: {
test: 'passed',
},
},
navigating: {
to: {
route: { id: '/storybook' },
params: {},
url: new URL('https:///storybook'),
},
},
updated: {
current: true,
},
},
},
},
};可以在 API 部分(下方)的可用参数中找到文档。
模拟链接
默认的链接处理行为(例如,在点击 <a href="..." /> 元素时)是将操作记录到操作面板。
您可以通过将一个对象赋给 parameters.sveltekit_experimental.hrefs 来覆盖此行为,其中键是表示 href 的字符串,值定义您的模拟。例如
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 参考。
编写原生 Svelte stories
Storybook 提供了一个由社区维护的 Svelte 插件,让您可以使用模板语法为 Svelte 组件编写 story。
社区积极维护 Svelte CSF 插件,但仍缺少一些官方 Storybook Svelte 框架支持中目前可用的功能。有关更多信息,请参阅插件文档。
设置
如果您使用 Sveltekit 框架初始化了项目,则已为您安装并配置了该插件。但是,如果您从以前的版本迁移,您将需要采取额外步骤来启用此功能。
运行以下命令来安装插件。
npx storybook@latest add @storybook/addon-svelte-csf更新您的 Storybook 配置文件(即 .storybook/main.js|ts)以启用对此格式的支持。
// Replace your-framework with svelte-vite or sveltekit
import type { StorybookConfig } from '@storybook/your-framework';
const config: StorybookConfig = {
stories: ['../src/**/*.stories.@(js|jsx|ts|tsx|svelte)'],
addons: [
// Other Storybook addons
'@storybook/addon-svelte-csf',
],
};
export default config;配置
默认情况下,Svelte 插件插件提供零配置支持 Storybook 的 SvelteKit 框架。但是,您可以扩展您的 Storybook 配置文件(即 .storybook/main.js|ts)并提供其他插件选项。下面列出了可用选项以及如何使用它们的示例。
// Replace your-framework with the name of your Svelte framework
import type { StorybookConfig } from '@storybook/your-framework';
const config: StorybookConfig = {
// Other configuration
addons: [
{
name: '@storybook/addon-svelte-csf',
options: {
legacyTemplate: true, // Enables the legacy template syntax
},
},
],
};
export default config;| 选项 | 描述 |
|---|---|
legacyTemplate | 启用对 Template 组件的支持,以实现向后兼容。options: { legacyTemplate: true } |
启用 legacyTemplate 选项可能会带来性能开销,应谨慎使用。有关更多信息,请参阅插件文档。
升级到 Svelte CSF 插件 v5
随着 Svelte 5 的发布,Storybook 的 Svelte CSF 插件已更新以支持新功能。本指南将帮助您迁移到插件的最新版本。下面概述了 5.0 版的主要更改以及升级项目所需的步骤。
简化的 story API
如果您使用 Meta 组件或 meta 命名导出(用于定义 story 的元数据,例如参数),您需要更新您的 stories 以使用新的 defineMeta 函数。此函数返回一个包含所需信息的对象,其中包括您必须用于定义组件 stories 的 Story 组件。
<script>
import { Meta, Story } from '@storybook/addon-svelte-csf';
import MyComponent from './MyComponent.svelte';
</script>
<Meta title="MyComponent" component={MyComponent} />
<Story name="Default" />Story 模板
如果您使用 Template 组件来控制组件在 Storybook 中的渲染方式,此功能已被 Story 组件中内置的 children 支持所取代,使您能够直接在 story 中组合组件并定义 UI 结构。
<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 组件的支持,该插件提供了用于向后兼容的功能标志。有关更多信息,请参阅配置选项。
Story 插槽到片段
随着 Svelte 插槽的弃用以及可重用snippets的引入,该插件还引入了对该功能的支持,允许您扩展 Story 组件并提供自定义片段以向您的 stories 提供动态内容。Story 接受一个 template 片段,允许您创建动态 stories 而不丢失响应性。
<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 template(args)}
<MyComponent {...args}>Reactive component</MyComponent>
{/snippet}
</Story>Tags 支持
如果您启用了使用 autodocs story 属性的自动文档生成,您必须将其替换为tags。此属性允许您根据应用于 stories 的特定条件对 stories 进行分类和过滤,并基于这些标签生成文档。
<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
参数
此框架将以下参数贡献给 Storybook,位于 sveltekit_experimental 命名空间下
forms
Type: { enhance: () => void }
提供 $app/forms 模块的模拟。
forms.enhance
Type: () => void
当提交带有 use:enhance 的表单时将调用一个回调。
hrefs
Type: Record<[path: string], (to: string, event: MouseEvent) => void | { callback: (to: string, event: MouseEvent) => void, asRegex?: boolean }>
如果您在代码中有一个 <a /> 标签,其中 href 属性匹配一个或多个定义的链接(如果 asRegex 属性为 true,则视为正则表达式),则将调用相应的 callback。如果未定义匹配的 hrefs,则会将操作记录到操作面板。有关示例,请参阅模拟链接。
navigation
Type: 请参阅SvelteKit 文档
提供 $app/navigation 模块的模拟。
navigation.goto
Type: 请参阅SvelteKit 文档
每次调用 goto 时将调用一个回调。如果未提供函数,则会将操作记录到操作面板。
navigation.pushState
Type: 请参阅SvelteKit 文档
每次调用 pushState 时将调用一个回调。如果未提供函数,则会将操作记录到操作面板。
navigation.replaceState
Type: 请参阅SvelteKit 文档
每次调用 replaceState 时将调用一个回调。如果未提供函数,则会将操作记录到操作面板。
navigation.invalidate
Type: 请参阅SvelteKit 文档
每次调用 invalidate 时将调用一个回调。如果未提供函数,则会将操作记录到操作面板。
navigation.invalidateAll
Type: 请参阅SvelteKit 文档
每次调用 invalidateAll 时将调用一个回调。如果未提供函数,则会将操作记录到操作面板。
navigation.afterNavigate
Type: 请参阅SvelteKit 文档
将传递给 afterNavigate 函数的对象,该函数将在 onMount 事件触发时调用。
stores
Type: 请参阅SvelteKit 文档
提供 $app/stores 模块的模拟。
stores.navigating
Type: 请参阅SvelteKit 文档
部分版本的 navigating store。
stores.page
Type: 请参阅SvelteKit 文档
部分版本的 page store。
stores.updated
Type: boolean
表示 updated 值的布尔值(您也可以访问 updated.check(),它将是 no-op)。
state
Type: 请参阅SvelteKit 文档
提供 $app/state 模块的模拟。
state.navigating
Type: 请参阅SvelteKit 文档
部分版本的 navigating store。
state.page
Type: 请参阅SvelteKit 文档
部分版本的 page store。
state.updated
Type: { current: boolean }
表示 updated 当前值的对象。您还可以访问 updated.check(),它将是 no-op。
选项
如果需要,您可以传递一个选项对象进行其他配置
import type { StorybookConfig } from '@storybook/sveltekit';
const config: StorybookConfig = {
// ...
framework: {
name: '@storybook/sveltekit',
options: {
// ...
},
},
};
export default config;可用选项为
builder
类型:Record<string, any>
配置框架构建器的选项。对于 Sveltekit,可以在Vite 构建器文档中找到可用选项。
docgen
类型:boolean
默认:true
启用或禁用组件属性的自动文档生成。禁用时,Storybook 将跳过构建过程中的 docgen 处理步骤,这可以提高构建性能。
import type { StorybookConfig } from '@storybook/sveltekit';
const config: StorybookConfig = {
framework: {
name: '@storybook/sveltekit',
options: {
docgen: false, // Disable docgen for better performance
},
},
};
export default config;何时禁用 docgen
禁用 docgen 可以提高大型项目的构建性能,但 argTypes 将不会自动推断,这将阻止 Controls 和 docs 等功能正常工作。要使用这些功能,您需要 手动定义 argTypes。
故障排除
启动 Storybook 时出错
在升级到 v7.0 后启动 Storybook 时,它可能会因以下错误而退出
ERR! SyntaxError: Identifier '__esbuild_register_import_meta_url__' has already been declared当手动从 6.5 升级到 7.0 时,可能会发生这种情况。要解决此问题,您需要删除 .storybook/main.js 中的 svelteOptions 属性,因为在 Storybook 7+ 的 SvelteKit 中不再支持(也不再需要)该属性。
