想法
Storybook 装饰器非常强大,但强大的能力伴随着巨大的责任。
一开始,定义全局装饰器是可以的。但随着项目的发展,不同的路径可能需要不同的管理或装饰器。
从维护的角度来看,为每个故事添加这些装饰器是不可扩展的。
那么,**在文件夹级别定义装饰器** 怎么样?
安装
通过添加 storybook-include
依赖项来安装此插件
yarn add -D storybook-include
在 .storybook/main.js 中
module.exports = {
addons: [
'storybook-include',
// or
require.resolve('storybook-include/preset'),
],
};
用法
-
故事文件无需更改,一切都可以在外部配置
-
在文件夹中创建一个
storybook.include.js
,或者.ts
或.jsx/.tsx
文件。可以是任何文件夹,包括你的主文件夹 -
配置需要包含哪些装饰器
-
它起作用了
配置
示例文件
// storybook.include.js
import { addStoryDecorators } from 'storybook-include';
// decorators are defined via default export
export default () => {
addStoryDecorators((story, { storyName, fileName }) => {
// you can mutate story
story.args = { decorated: true };
// you can add decorators
story.decorators.push(myDecorator);
// you can return an array of decorators to add
return storyName.includes('dark') ? [darkModeDecorator] : undefined;
});
// another set
addStoryDecorators((story, { fileName }) => {
return fileName.includes('page') ? [ReactRouterDecorator, StaticRouterDecorator] : undefined;
});
// another set
addStoryDecorators((story) => {
return [CSSInJS, Theme, AndSomethingElse];
});
};
复用配置
在极少数情况下,你可能会考虑在两个配置文件之间共享相同的配置。虽然简单复制通常更受欢迎,但还有一种更简单的方法可以做到
// storybook.include
import another from '../../other/storybook.include';
// ^ it's from another "branch", all explit parents will be "included" in any case
export default () => {
// do you thing
another();
};
用于非 .stories.*
文件
有时可以使用非标准的故事文件名 - .story.*
、example.*
等。在这种情况下,默认预设将不起作用,需要一个自定义预设
// your custom preset
/* eslint-disable no-param-reassign */
export function babel(options) {
options.overrides = options.overrides || [];
options.overrides.push({
test: /\.stories\.tsx?/, // <-- pattern matching your stories
plugins: [require.resolve('storybook-include/babel')],
});
return options;
}
缓存注意事项
虽然 Storybook 不强制构建缓存,但此插件在构建时考虑了缓存。因此,每个文件都会“自动配置”其上方所有“包含文件”,并且每个其他文件都可以“重新配置”该列表。
理论上,这会影响非缓存系统的性能。
⛔️ 删除或重命名包含文件可能需要更新缓存。
另请参阅
- storybook-csf-title - 一个语义相近的插件 - 根据故事文件的位置为 Storybook 创建
title
。
许可
MIT