
React Native Storybook (6.5)
性能改进,支持组件 Story 格式 (CSF)、Controls 和 Args。此外,还采用新的配置文件格式以与 Storybook 核心保持一致。
React Native Storybook 是 Storybook 的一个专门版本,专注于为使用 React Native 构建的组件创建和组织 stories,而不是针对 HTML 和 CSS。与核心 Storybook 不同,React Native Storybook 在原生模拟器或物理移动设备上运行 stories,而不是在浏览器中。随着时间的推移,这种分歧导致 React Native Storybook 落后于浏览器版本的更新。
我很高兴地宣布 React Native Storybook 的新版本,现已兼容 Storybook 6.5.14 及更高版本。这个迭代简化了代码库,集成了更多的 Storybook 核心包,并提供了改进的开发者体验。
- 📝 支持组件 Story 格式 (CSF)
- 🎛️ 支持 Controls 和 Args(包括实验性的自动生成 Controls)
- 📜 与核心格式对齐的配置(
main.js
和preview.js
文件) - ⚡ 性能改进
- 🎨 设备端 UI 改进
为什么选择 6.5 版本?
为了让 React Native Storybook 与 Storybook 6.5 配合使用,Storybook 本身需要进行一些更改。因此,React Native Storybook 仅兼容 Storybook 6.5.14 及更高版本。这种权衡将使得 React Native Storybook 更容易与未来的 Storybook 版本集成,包括 Storybook 7.0。
这个版本是多年来许多周末和深夜努力的结果。很高兴终于能和大家分享它。我要感谢社区中所有人的耐心等待,以及帮助实现这一目标的贡献者们。此外,我还要感谢许多 Storybook 维护者,他们与我结对合作,共同攻克了更新中最复杂的部分。
让我们深入了解更新!

组件 Story 格式 (CSF) 支持
CSF 是 Storybook 更简单、更强大的语法,它使得 stories 更易于阅读、编写和维护。它基于 ES6 模块,使用命名导出定义 stories,使用默认导出定义元数据。React Native Storybook 现在支持 CSF。
使用 CSF,stories 以纯 JavaScript 对象编写。组件 props 使用 “Args” 指定,这是 Storybook 用于为 props 和 children 设置默认值的机制。
我们提供了一个 codemod 来简化此迁移(请参阅下面的迁移指南)。
import Button from './Button';
// The default export has metadata for your component story
export default {
title: "Button"
component: Button
};
// An individual story with some default props
export const Base = {
args: {
// default value for the 'text' property of this component
text: "Hello World"
}
};

使用 Controls 通过图形化 UI 操纵 props
Controls 允许您无需编写代码即可与组件的 args 进行交互。Storybook 会根据组件的 PropTypes 和 TypeScript 类型自动生成 Controls。就像旧的 Knobs 插件一样,您可以使用插件面板实时编辑参数。

默认情况下,Storybook 根据 arg 的类型选择输入控件(如文本、单选、选择和范围)。您可以通过配置 argTypes 来为每个 arg 选择要使用的控件类型。请查阅 Controls 文档了解更多信息。
import Button from "./Button";
// The default export has metadata for your component story
export default {
title: "Button",
component: Button,
// You can be more specfic about the type you want by using argTypes
argTypes: {
variant: {
options: ["primary", "secondary"],
control: { type: "radio" },
},
},
};
// An individual story with some default props
export const Primary = {
args: {
// default value for the 'text' property of this component
text: "Hello World",
variant: "primary",
},
};
与 Storybook 核心对齐的配置格式
自 React Native 版本分歧以来,Storybook 核心最大的变化之一是切换到使用 main.js
和 preview.js
文件实现的更具声明性的配置格式。为了与 Storybook 核心对齐,React Native Storybook 现在也使用这种格式。
在 main.js
文件中,在 stories 字段中提供一个 glob 模式,并列出插件。然后 Storybook 会处理其余部分,生成一个名为 storybook.requires.js
的文件。preview.js
文件用于定义全局装饰器和参数。
更多关于语义的内容请参阅下面的升级指南。继续阅读以查看一些示例。
开始使用
如果您正在启动一个新项目,请在 React Native 项目中运行此命令以自动生成所需的配置。
npx sb@next init --type react_native
如果您愿意,也可以使用以下模板之一。
# Expo
npx create-expo-app --template expo-template-storybook AwesomeStorybook
# React Native CLI
npx react-native init MyApp --template react-native-template-storybook
如果您是 React Native Storybook 的新手,请查看我们的实践教程以学习所有基础知识:https://storybook.org.cn/tutorials/intro-to-storybook/react-native/en/get-started/
如何升级
步骤 1:更新您的 index 文件
从您的 index.js
文件中移除 configure 调用、story 导入和 addon 导入,并将文件简化为此。最重要的是导入 storybook.requires
文件。
// .storybook/index.js
import { getStorybookUI } from '@storybook/react-native';
import './storybook.requires';
const StorybookUIRoot = getStorybookUI({
// options go here
});
export default StorybookUI
此外,如果您的 Storybook 文件夹名为 storybook
,您应将其更改为 .storybook
步骤 2:添加新的配置文件
在您的 .storybook
文件夹中,添加 main.js
和 preview.js
文件。
在您的 main.js
文件的 stories 字段中,根据您的项目设置更新 glob 模式。
在 addons 字段中,列出您要使用的插件。这些插件必须兼容 React Native Storybook。为 React Native 构建的插件通常以 addon-ondevice
为前缀。
// .storybook/main.js
module.exports = {
stories: [
'../components/**/*.stories.?(ts|tsx|js|jsx)',
],
addons: [
'@storybook/addon-ondevice-controls',
'@storybook/addon-ondevice-actions',
'@storybook/addon-ondevice-backgrounds',
],
};
将您拥有的所有全局装饰器和参数移至 preview.js
。如果您没有任何全局装饰器和参数,只需分别为 decorators 导出一个空数组,为 parameters 导出一个空对象。
// .storybook/preview.js
import { View } from 'react-native';
export const decorators = [
// Using a decorator to apply padding for every story
(StoryFn) => (
<View style={{flex:1, padding:8}}>
<StoryFn />
</View>
),
];
export const parameters = {
my_param: 'anything',
};
步骤 3:将您的 stories 转换为 CSF
虽然 storiesOf
仍然可用,但它已被弃用,我们建议您将 stories 转换为 CSF。为了方便起见,我们提供了一个 codemod,它应该会自动将您的文件迁移到 CSF(请确保更新 glob 模式以匹配您的文件)。
npx storybook@next migrate storiesof-to-csf --glob="src/**/*.stories.js"
让我们看一个例子。我们将使用这个 Button.stories.js
文件
// Button.stories.js
// Before
storiesOf('Button', module)
.addParameters({ myParam: "anything" })
.addDecorator((Story)=> <Wrapper>{Story}</Wrapper>)
.add('primary', () => <Button primary label="Button" />)
.add('secondary', () => <Button label="Button" />);
codemod 会将其转换为 CSF,如下所示
// Button.stories.js (CSF1)
export default {
title: 'Button',
decorators: [(Story) => <Wrapper>{Story}</Wrapper>],
parameters: {
myParam: 'anything',
},
};
export const Primary = () => <Button primary label="Button" />;
Primary.story = {
name: 'primary',
};
export const Secondary = () => <Button label="Button" />;
Secondary.story = {
name: 'secondary',
};
CSF 被设计为向后兼容,这使得 Storybook 团队能够持续改进。最新的 story 格式 CSF3 包含了一些人体工程学方面的改进。请参阅发布公告,了解所有功能和优势的完整列表。
最后,我们可以手动将文件更新为 CSF3 格式,如下所示
// Button.stories.js (CSF3)
export default {
title: 'Button',
decorators: [(Story) => <Wrapper>{Story}</Wrapper>],
parameters: {
myParam: 'anything',
},
};
export const Primary = {
args: {
primary: true,
label: 'Button',
},
};
export const Secondary = {
args: {
label: 'Button',
},
};
注意,如果您正在使用 Knobs 插件,请考虑迁移到 Controls。
可选:服务器配置
服务器是一个名为 @storybook/react-native-server
的包。它是一个可选的配套应用程序,允许您通过 Web UI 控制设备上的 React Native Storybook UI。
在此版本中,服务器的配置略有变化。要配置服务器,您需要添加一个 .storybook_server
文件夹,其中包含一个 main.js
文件。在此文件中,您应该添加与 .storybook/main.js
文件中相同的 stories glob 模式。
module.exports = {
stories: [
'../components/**/*.stories.?(ts|tsx|js|jsx)',
],
env: () => ({}),
addons: ['@storybook/addon-essentials'],
};
然后,在 package.json
中,您需要添加一个新的脚本
"start-server": "react-native-storybook-server"
有关此服务器设置的更多信息,请阅读这篇博文。
迁移问题?
有关此升级的更多详细信息,请参阅迁移指南。如果您遇到任何困难,可以在 GitHub 上提出 issue 或访问 Storybook Discord。
下一步是什么?
React Native Storybook 6.5 带来了一些重大改进,但我们尚未完成。以下是您可以对 React Native Storybook 抱有的期望。
稳定 6.5 版本: 这是我们目前的首要任务。为了帮助我们实现这一目标,请在 React Native Storybook GitHub 上向我们报告任何 bug 并分享您的反馈。
支持 Storybook 7.0: 随着 6.5 版本的发布,与 Storybook 7.0 版本兼容的基础工作已经基本完成。6.5 版本稳定后,将开始进行这方面的工作。
改进
未来更新有许多可能的方向,以下是我的一些改进想法。
- 支持 story 分类,以便在 story 列表侧边栏中更好地组织
- 使用 metro 的实验性
require.context
简化 story 导入 - 更好的测试支持,包括可能支持带有 play 函数的交互测试
- 更好地集成
@storybook/addon-react-native-web
我们还可以做很多其他事情,我们很想听听您关于下一步应该关注哪些方面的想法。
总结
React Native Storybook 由我,Daniel Williams 维护。这次更新为 React Native Storybook 带来了许多改进,并缩小了与最新 Storybook 版本之间的差距。
仍有很多地方可以改进,版本 7 肯定在我的计划中。如果您对这个项目感兴趣并想提供帮助,请联系我,我很乐意帮助您入门。此外,您可以访问 GitHub 仓库来创建 issue、提交 pull request 和发起讨论。
您可以在 Twitter (@Danny_H_W) 或 Github (dannyhw) 上找到我。如果您想支持我的工作,请考虑通过 GitHub Sponsors 赞助我。感谢您的阅读,期待您的反馈。
React Native Storybook (6.5) 来了!
— Storybook (@storybookjs) 2023年3月29日
有什么新内容?
✅ 兼容 SB 6.5.14+
📝 支持 CSF, Controls & Args
📜 核心风格配置格式 (main.js & preview.js 文件)
⚡ 性能改进
🎨 设备端 UI 改进https://#/1GPVVDjuY2
🧵/ pic.twitter.com/ko1eOrXnl2