为 React Native/TypeScript 设置 Storybook(服务器、加载器、iOS、Android)
Storybook 示例 React Native TypeScript
技术栈
如何使用
我最近为一个 React Native/TypeScript 项目配置了 Storybook。它和在 Web 开发中使用 Storybook 并没有太大区别,但也存在一些问题。我发现他们的 官方教程 有时会过时,而他们的 GitHub README 虽然是最新的,但并没有包含我需要的所有信息。
本文将一步一步地演示如何为 React Native 设置 Storybook,包括 web UI ( @storybook/react-native-server)、动态故事加载 ( react-native-storybook-loader) 和 TypeScript。
已完成的仓库:
为 React Native/TypeScript 项目设置 Storybook 的示例仓库。
Storybook 示例 React Native TypeScript
这个仓库展示了我为个人 React Native 项目(包含在一个单独的私有仓库中)制作的一些组件。
我写了一篇关于 Storybook 设置过程的博文,链接如下:
https://dev.to/risafj/setting-up-storybook-for-react-native-typescript-server-loader-ios-android-3b0i
技术栈
React Native
TypeScript
故事书
@storybook/react-native-server使用网页界面
react-native-storybook-loader用于动态故事加载
Lint:ESLint(标准 JS 格式)
CI:GitHub Actions
如何使用
克隆此仓库
yarn install
如果你使用的是iOS模拟器, npx pod-install
创建 .env文件
复制以下内容 .env.sample
yarn storybook启动 Storybook 服务器 (localhost:7007)
yarn ios或者 yarn android在模拟器中启动 Storybook
注意:要启动 Storybook,必须设置环境变量(如上文步骤 4 和 5 LOAD_STORYBOOK所示 true)。否则,它将启动 React Native CLI 创建的默认应用程序。
先决条件
既然你在阅读这篇文章,我就假设你已经使用 React Native CLI 设置了一个项目。
注意:我不能保证这些步骤同样适用于 Expo 项目。
步骤 1:安装 Storybook
请在项目根目录运行以下命令。这将安装必要的软件包并自动添加样板代码。
npx -p @storybook/cli sb init --type react_native
Enter fullscreen mode
Exit fullscreen mode
当系统提示是否安装时 @storybook/react-native-server,请选择“是”。Storybook Server 包的作用是让你使用 Web 界面来切换组件和调整参数,而无需在模拟器中完成所有操作(它的用户界面与其他框架的 Storybook 相同)。
这就是它在网页界面上的样子:
如果你正在为 iOS 开发,你也应该 pod install从该 ios/目录运行一个命令。
步骤 2:有条件地渲染 Storybook
现在,让我们添加环境变量 LOAD_STORYBOOK,并使用此标志来确定我们应该加载实际的应用程序还是 Storybook。
注意:这是 Storybook 的README 中推荐的方法之一 。
添加 LOAD_STORYBOOK标志
在 React Native 中使用环境变量的方法有很多种,但我使用的是 react-native-config。 设置非常简单:
yarn add react-native-config, 然后 pod install
如果您正在开发 Android 版本,请按照此处的 说明添加导入语句。
在项目根目录下,创建一个 .env文件
您添加的任何环境变量 .env都可以作为访问变量。 Config.YOUR_ENVIRONMENT_VARIABLE
现在,将环境变量添加 LOAD_STORYBOOK=true到 .env.
如果渲染故事书 LOAD_STORYBOOK=true
在代码中 App.tsx,按如下方式更改代码,以便 Storybook 可以根据条件进行渲染。
import StorybookUI from ' ./storybook '
import Config from ' react-native-config '
const App = () => {
return (
// Your actual app
)
}
export default Config . LOAD_STORYBOOK === ' true ' ? StorybookUI : App
Enter fullscreen mode
Exit fullscreen mode
步骤 3:启动故事书
还有一些其他设置需要调整,但目前你应该能够启动 Storybook 并确保它能够正常工作。
首先,使用以下命令启动 Storybook 服务器(Web 界面):
yarn storybook
Enter fullscreen mode
Exit fullscreen mode
启动完成后,应该会打开一个类似这样的浏览器窗口(如果没有,您可以直接访问 localhost:7007):
此时,侧边栏菜单应该显示加载动画。
接下来,运行 yarn ios或 yarn android。由于我们设置了 LOAD_STORYBOOK=true,这将运行 Storybook 而不是您的实际应用程序。
启动后,Storybook 服务器的侧边栏应该会显示你拥有的故事,允许你通过 Web UI 进行导航(如步骤 1 中的 GIF)。
如果 Storybook Server 无法在 Android 模拟器上运行,请执行以下步骤
对于 Android 系统,您可能会发现即使 Storybook 已在模拟器中启动,侧边栏也不会显示内容。GitHub 上有一些 issue(例如 这个 )讨论了这种现象。我在网上找到的建议是运行 `Storybook install` adb reverse tcp:7007 tcp:7007,但最终,我的解决方法是将 host 参数指定为 Android 本地主机。
// storybook/index.js
const StorybookUIRoot = getStorybookUI ({
// Add the line below
host : Platform . OS === ' android ' ? ' 10.0.2.2 ' : ' 0.0.0.0 '
});
Enter fullscreen mode
Exit fullscreen mode
步骤 4:处理 asyncStorage 警告
您可能会在 Metro 服务器日志中看到类似这样的警告:
WARN Starting Storybook v5.3.0, we require to manually pass an asyncStorage prop. Pass null to disable or use one from @react-native-community or react-native itself.
根据 文档 :
使用异步存储的好处是,当用户刷新应用时,Storybook 可以打开他们上次访问的故事。
配置起来很简单;只需按如下方式传入即可。
注意:如果您没有该 @react-native-community/async-storage软件包,则需要先安装它。
// storybook/index.js
const StorybookUIRoot = getStorybookUI ({
host : Platform . OS === ' android ' ? ' 10.0.2.2 ' : ' 0.0.0.0 ' ,
// Add the line below
asyncStorage : require ( ' @react-native-community/async-storage ' ). default
});
Enter fullscreen mode
Exit fullscreen mode
步骤 5:添加 Storybook 加载器
从技术上讲,使用 Storybook 并非必须使用 React Native Storybook Loader,但它是一个便捷的插件,可以让你免去为每个故事文件编写导入语句的麻烦。Storybook Loader 会在你启动 Storybook 时执行一个脚本,该脚本会自动生成一个包含必要导入语句的文件。
他们的官方 README 文件中的快速入门部分涵盖了你需要的所有内容,所以我在这里附上链接: https://github.com/elderfo/react-native-storybook-loader#quick-start
第六步:用 TypeScript 编写你自己的故事!
现在,剩下的就是添加你自己的故事(并删除不必要的样板代码)。你无需添加任何包或配置即可用 TypeScript 编写故事;只需使用该 .stories.tsx扩展即可。 以下是一个示例:
// src/components/atoms/CustomButton.stories.tsx
import { storiesOf } from ' @storybook/react-native '
import { CenterView } from ' ../../../storybook/stories/CenterView '
import React from ' react '
import { CustomButton } from ' ./CustomButton '
storiesOf ( ' Atoms/CustomButton ' , module )
. addDecorator (( getStory ) => < CenterView > { getStory () } </ CenterView >)
. add ( ' confirm ' , () => (
< CustomButton text = "Confirm" colorModifier = "confirm" />
))
Enter fullscreen mode
Exit fullscreen mode
注意
如果您计划重用 CenterView`<script>` 组件(该组件用于将您的故事代码放置在模拟器屏幕的中心),则需要使用 TypeScript 重写它,否则会遇到类型错误。这非常简单——只需像这样重写即可(具体更改请参 见此提交 ):
// storybook/stories/CenterView/index.tsx
import React from ' react '
import { StyleSheet , View } from ' react-native '
interface Props {
children : any
}
export const CenterView = ( props : Props ) => {
return (
< View style = { styles . main } >
{ props . children }
</ View >
)
}
const styles = StyleSheet . create ({
main : {
flex : 1 ,
justifyContent : ' center ' ,
alignItems : ' center ' ,
backgroundColor : ' #F5FCFF ' ,
}
})
Enter fullscreen mode
Exit fullscreen mode
感谢阅读!
鸣谢: 非常感谢 @rob117 ,他帮助解决了 Storybook 服务器和 Android 模拟器之间的兼容性问题。
文章来源:https://dev.to/risafj/setting-up-storybook-for-react-native-typescript-server-loader-ios-android-3b0i