编写预设插件
Storybook 预设是预先配置的设置或配置,使开发人员能够快速设置和自定义其环境,并具有一组特定的特性、功能或集成。
预设的工作原理
预设插件允许开发人员通过 API 组合各种配置选项和插件,以与 Storybook 集成并自定义其行为和功能。通常,预设分为两个文件,每个文件都有其特定的角色。
本地预设
这种类型的预设允许您封装和组织特定于插件的配置,包括构建器支持、Babel 或第三方集成。例如
import { webpackFinal as webpack } from './webpack/webpackFinal';
import { viteFinal as vite } from './vite/viteFinal';
import { babelDefault as babel } from './babel/babelDefault';
export const webpackFinal = webpack as any;
export const viteFinal = vite as any;
export const babelDefault = babel as any;
根级别预设
这种类型的预设面向用户,负责注册插件,而无需用户进行任何额外的配置,方法是通过 previewAnnotations
API 捆绑 Storybook 相关功能(例如,parameters 参数),以及通过 managerEntries
API 捆绑 UI 相关功能(例如,插件)。例如
export const previewAnnotations = [require.resolve('./dist/preview')];
export const managerEntries = [require.resolve('./dist/manager')];
export * from './dist/preset';
预设 API
编写预设时,您可以访问一组精选的 API,以与 Storybook 环境(包括支持的构建器(例如,Webpack、Vite)、Storybook 配置和 UI)进行交互。以下是编写预设插件时可以使用的可用 API。
Babel
要自定义 Storybook 的 Babel 配置并添加对其他功能的支持,您可以使用 babelDefault
API。它将在任何其他用户预设之前应用提供的配置,最终用户可以通过 babel
配置选项进一步自定义该配置。例如
import { TransformOptions } from '@babel/core';
export function babelDefault(config: TransformOptions) {
return {
...config,
plugins: [
...config.plugins,
[require.resolve('@babel/plugin-transform-react-jsx'), {}, 'preset'],
],
};
}
构建器
默认情况下,Storybook 提供对主要行业构建器的支持,包括 Webpack 和 Vite。如果您需要这些构建器的任何其他功能,可以使用 API 根据您的特定需求扩展构建器配置。
Vite
如果您正在创建预设并希望包含 Vite 支持,则可以使用 viteFinal
API 来修改默认配置并启用其他功能。例如
export function ViteFinal(config: any, options: any = {}) {
config.plugins.push(
new MyCustomPlugin({
someOption: true,
}),
);
return config;
}
Webpack
要自定义 Storybook 中的 Webpack 配置,以添加对其他文件类型的支持、应用特定的加载器、配置插件或进行任何其他必要的修改,您可以使用 webpackFinal
API。调用后,它将使用提供的配置扩展默认的 Webpack 配置。一个例子是:
import type { Configuration as WebpackConfig } from 'webpack';
export function webpackFinal(config: WebpackConfig, options: any = {}) {
const rules = [
...(config.module?.rules || []),
{
test: /\.custom-file$/,
loader: require.resolve(`custom-loader`),
},
];
config.module.rules = rules;
return config;
}
ManagerEntries
如果您正在编写一个加载第三方插件的预设(您可能无法控制这些插件,但需要访问特定功能或其他配置),则可以使用 managerEntries
API。例如
export const managerEntries = (entry = []) => {
return [...entry, require.resolve('path-to-third-party-addon')];
};
PreviewAnnotations
如果您需要其他设置来渲染预设的 stories,例如 decorators 装饰器或 parameters 参数,则可以使用 previewAnnotations
API。例如,要将装饰器应用于所有 stories,请创建一个包含装饰器的预览文件,并使其可用于预设,如下所示
import type { Renderer, ProjectAnnotations } from '@storybook/types';
import { PARAM_KEY } from './constants';
import { CustomDecorator } from './decorators';
const preview: ProjectAnnotations<Renderer> = {
decorators: [CustomDecorator],
globals: {
[PARAM_KEY]: false,
},
};
export default preview;
高级配置
预设 API 旨在灵活,并允许您根据特定需求自定义 Storybook,包括在不发布预设的情况下将其用于更高级的用例。在这种情况下,您可以依赖私有预设。这些私有预设包含用于开发目的而不是最终用户的配置选项。.storybook/main.js|ts
文件就是这样一个私有预设的示例,它使您能够修改 Storybook 的行为和功能。
// Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
import type { StorybookConfig } from '@storybook/your-framework';
const config: StorybookConfig = {
viteFinal: async (config, options) => {
// Update config here
return config;
},
webpackFinal: async (config, options) => {
// Change webpack config
return config;
},
babel: async (config, options) => {
return config;
},
};
export default config;
插件
对于插件使用者,managerEntries
API 可能过于技术性,难以使用。为了更轻松地将插件添加到 Storybook,预设 API 提供了 addons
API,该 API 接受插件名称数组,并将自动为您加载它们。例如
// Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
import type { StorybookConfig } from '@storybook/your-framework';
const config: StorybookConfig = {
addons: [
// Other Storybook addons
'@storybook/addon-a11y',
],
};
export default config;
值数组支持对其他应包含在管理器中的预设和插件的引用。 Storybook 将自动检测提供的值是预设还是插件,并相应地加载它。
入口点
入口点是注册预览入口点的位置。此功能可用于创建 configure-storybook 预设,该预设自动将所有 *.stories.js
文件加载到 Storybook 中,从而无需用户重复复制粘贴相同的配置。
UI 配置
Storybook 预设 API 还提供对 UI 配置的访问,包括预览的 head
和 body
HTML 元素,这些元素由 previewHead
和 previewBody
API 配置。两者都允许您以类似于使用 preview-head.html
和 preview-body.html
文件的方式设置 Storybook。这些方法都接受一个字符串并返回修改后的版本,将提供的内容注入到 HTML 元素中。
// Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
import type { StorybookConfig } from '@storybook/your-framework';
const config: StorybookConfig = {
previewBody: (body) => `
${body}
${
process.env.ANALYTICS_ID ? '<script src="https://cdn.example.com/analytics.js"></script>' : ''
}
`,
};
export default config;
此外,如果您需要自定义管理器(即 Storybook 的搜索、导航、工具栏和插件的渲染位置),则可以使用 managerHead
来修改 UI,类似于使用 manager-head.html
文件的方式。例如
// Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
import type { StorybookConfig } from '@storybook/your-framework';
const config: StorybookConfig = {
managerHead: (head) => `
${head}
<link rel="icon" type="image/png" href="/logo192.png" sizes="192x192" />
`,
};
export default config;
但是,如果需要,您也可以自定义 Storybook 用于渲染 UI 的模板。为此,您可以使用 previewMainTemplate
API,并提供作为 ejs
文件创建的自定义模板的引用。有关如何执行此操作的示例,请参阅 Webpack 5 构建器使用的模板。
故障排除
Storybook 未加载我的预设中的文件
由于 Storybook 依赖 esbuild 而不是 Webpack 来构建 UI,因此依赖于 managerWebpack
API 来配置管理器或加载 CSS 或图像以外的其他文件的预设将不再起作用。我们建议从您的预设中删除它,并调整您的配置以将任何其他文件转换为 JavaScript。
了解有关 Storybook 插件生态系统的更多信息