React Native配置Storybook切换后,执行命令仍启动主应用
Expo + React Native Storybook 切换失效问题
我按照Storybook官方React Native入门教程配置CLI命令,想要实现Storybook与主应用的切换,具体操作如下:
- 编写了
app.config.js文件:
module.exports = { name: 'mobile-app', slug: 'mobile-app', version: '1.0.0', extra: { storybookEnabled: process.env.STORYBOOK_ENABLED, }, orientation: 'portrait', icon: './assets/icon.png', userInterfaceStyle: 'light', splash: { image: './assets/splash.png', resizeMode: 'contain', backgroundColor: '#ffffff', }, assetBundlePatterns: ['**/*'], ios: { supportsTablet: true, }, android: { adaptiveIcon: { foregroundImage: './assets/adaptive-icon.png', backgroundColor: '#ffffff', }, }, web: { favicon: './assets/favicon.png', }, };
- 更新了
App.tsx,添加切换逻辑:
import { StatusBar } from 'expo-status-bar'; import { StyleSheet, View } from 'react-native'; import Constants from 'expo-constants'; import { ThemeProvider } from '@rneui/themed'; import theme from './styles/theme'; import { Text } from './components/Text/Text'; function App() { const styles = StyleSheet.create({ container: { alignItems: 'center', backgroundColor: theme.lightColors?.gold120, flex: 1, justifyContent: 'center', }, }); return ( <ThemeProvider theme={theme}> <View style={styles.container}> <Text h3>Whereas recognition of the inherent dignity</Text> <StatusBar style="auto" /> </View> </ThemeProvider> ); } let AppEntryPoint = App; // Render Storybook if storybookEnabled is true if (Constants.expoConfig?.extra?.storybookEnabled === 'true') { /* eslint-disable-next-line @typescript-eslint/no-var-requires */ AppEntryPoint = require('./.storybook').default; } export default AppEntryPoint;
注:我添加了可选链操作符,并为TypeScript添加了ESLint禁用规则。
- 在
package.json中添加脚本:
"scripts": { // ...其他脚本 "storybook": "sb-rn-get-stories STORYBOOK_ENABLED='true' && expo start" },
由于是Windows设备,我移除了官方文档中STORYBOOK_ENABLED前的&&。
预期执行yarn start启动主应用,yarn storybook启动Storybook,但实际执行yarn storybook时始终启动主应用,请问哪里配置错了?
问题原因及修复方案
1. Windows环境变量传递方式错误
Windows的CMD/PowerShell环境下,环境变量的设置语法和Unix系完全不同,你当前的写法无法把STORYBOOK_ENABLED变量正确传递到Expo的配置中。
修复方式:
- 如果你用CMD终端,修改脚本为:
"storybook": "set STORYBOOK_ENABLED=true && sb-rn-get-stories && expo start"
- 如果你用PowerShell终端,修改脚本为:
"storybook": "$env:STORYBOOK_ENABLED='true'; sb-rn-get-stories; expo start"
- 想要兼容所有终端,推荐用
cross-env统一环境变量设置:
先安装依赖:
再修改脚本:yarn add cross-env --dev"storybook": "cross-env STORYBOOK_ENABLED=true sb-rn-get-stories && expo start"
2. 检查.storybook入口文件是否正确
确认.storybook目录下的index.js/index.ts存在且正确导出Storybook组件,示例结构:
import { getStorybookUI, configure, addDecorator } from '@storybook/react-native'; import { withTheme } from '@storybook/addon-themes'; import './rn-addons'; // 导入所有stories文件 configure(() => { require('../stories'); }, module); // 添加装饰器(按需配置) addDecorator(withTheme); // 获取Storybook UI根组件 const StorybookUIRoot = getStorybookUI({ asyncStorage: require('@react-native-async-storage/async-storage').default, }); export default StorybookUIRoot;
3. 清除Expo缓存
缓存可能导致配置不生效,执行以下命令强制清除缓存后再启动:
expo start -c
也可以直接把清除缓存加入脚本:
"storybook": "cross-env STORYBOOK_ENABLED=true sb-rn-get-stories && expo start -c"
4. 验证环境变量是否传递成功
在app.config.js中添加日志,确认变量是否被正确读取:
console.log('STORYBOOK_ENABLED:', process.env.STORYBOOK_ENABLED); module.exports = { // ...原有配置内容 };
启动时查看终端输出,确认STORYBOOK_ENABLED的值为true。
内容的提问来源于stack exchange,提问作者Andrew Bautista
相关产品推荐
相关产品推荐

