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

组件故事格式 (CSF) 支持
CSF 是 Storybook 中一种更简单、更强大的语法,可以更轻松地读取、编写和维护故事。它基于 ES6 模块,使用命名导出定义故事,并使用默认导出定义元数据。React Native Storybook 现在支持 CSF。
使用 CSF,故事被写成纯 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 addon 类似,您可以使用插件面板实时编辑参数。

默认情况下,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/
如何升级
第一步:更新您的 index 文件
从您的 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
第二步:添加新的配置文件
在您的 .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',
};
第三步:将您的故事转换为 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。
在此版本中,服务器的配置已稍作更改。要配置服务器,您需要添加一个 .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 上提出问题或访问 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.0 版本绝对在我考虑范围内。如果您对这个项目感兴趣并想提供帮助,请联系我,我很乐意协助您开始。此外,您可以访问 GitHub 仓库来创建 issues、打开 pull requests 和发起讨论。
您可以在 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