
React Native 的 Storybook (6.5)
性能改进,支持组件故事格式,控件和参数。以及新的配置文件格式,以与 Storybook 核心对齐。
React Native Storybook 是 Storybook 的一个专门版本,专注于为使用 React Native 而不是 HTML 和 CSS 构建的组件创建和组织故事。与核心 Storybook 不同,React Native Storybook 在原生模拟器或物理移动设备而不是浏览器上运行故事。随着时间的推移,这种差异导致 React Native Storybook 落后于浏览器版本的更新。
我很高兴地宣布一个 React Native Storybook 的新版本,现在兼容 Storybook 6.5.14 及更高版本。此迭代简化了代码库,整合了更多核心 Storybook 包,并提供了改进的开发者体验。
- 📝 组件故事格式 (CSF) 支持
- 🎛️ 控件和参数 (Args) 支持(包括实验性的自动生成控件)
- 📜 与核心格式对齐的配置 (
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 维护者,他们与我合作完成了更新中最复杂的部分。
让我们深入了解更新内容!

组件故事格式 (CSF) 支持
CSF 是一种更简单、更强大的 Storybook 语法,使故事更易于阅读、编写和维护。它基于 ES6 模块,使用命名导出定义故事,并使用默认导出定义元数据。React Native Storybook 现在支持 CSF。
使用 CSF,故事被编写为纯 JavaScript 对象。组件属性使用 “参数 (Args)” 指定,这是 Storybook 用于设置属性和子元素默认值的机制。
我们提供了一个 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) 通过图形用户界面操作属性
控件允许您与组件的参数 (args) 交互,而无需编写代码。Storybook 从组件的 PropTypes 和 TypeScript 类型自动生成控件。与旧的 Knobs 插件 类似,您可以使用插件面板实时编辑参数。

默认情况下,Storybook 根据参数的类型选择输入控件(例如文本、单选、选择和范围)。您可以通过配置 argTypes 来选择每个参数要使用的控件类型。查看控件 文档 以了解更多信息。
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.js 文件
中删除 configure 调用、故事导入和插件导入,并将文件简化为此。最重要的是导入 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
。如果您没有任何,只需为装饰器导出一个空数组,为参数导出一个空对象。
// .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:将您的故事转换为 CSF
虽然 storiesOf
仍然可以工作,但现在已弃用,我们建议您将故事转换为 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 团队能够持续改进。最新的故事格式 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。
在此版本中,服务器的配置略有变化。要配置服务器,您需要添加一个包含 main.js
文件的 .storybook_server
文件夹。在此文件中,您应该添加与 .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 上与我们分享您的反馈。
支持 Storybook 7.0: 随着 6.5 版本的发布,与 Storybook 7 版本的兼容性的大部分基础工作已经完成。一旦 6.5 版本稳定下来,这项工作将开始。
改进
对于未来的更新,我们可以采取许多方向,以下是我对改进的一些想法。
- 支持故事分类,以便在故事列表侧边栏中进行更多组织
- 使用 metro 的实验性
require.context
来简化故事导入 - 更好的测试支持,包括可能支持使用 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