You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native中如何搭配主项目使用Storybook并避免重复构建?

无需重新构建即可切换Storybook与React Native主应用的方案

嘿,这个问题我之前帮不少开发者解决过——完全不用每次切换都重新构建应用!咱们核心思路是让App根据配置动态切换加载主应用或Storybook,只需要一次构建,之后通过刷新就能快速切换。下面是具体的实现步骤:

方法一:通过环境变量动态切换入口

这是最常用的方案,通过启动时的环境变量来控制加载哪个模块,不用修改App代码就能切换。

1. 修改项目入口文件(index.js)

把原来直接注册主应用的代码改成根据环境变量判断:

import { AppRegistry } from 'react-native';
import App from './App';
import { name as appName } from './app.json';
import StorybookUI from './storybook';

// 根据环境变量决定加载Storybook还是主应用
const useStorybook = process.env.STORYBOOK_ENABLED === 'true';

AppRegistry.registerComponent(appName, () => useStorybook ? StorybookUI : App);

2. 配置跨平台环境变量脚本

因为不同系统设置环境变量的方式不同,先安装cross-env来统一跨平台的环境变量设置:

npm install cross-env --save-dev

然后修改package.json里的scripts:

"scripts": {
  "start": "react-native start",
  // 启动Storybook模式的Metro服务
  "start:storybook": "cross-env STORYBOOK_ENABLED=true react-native start",
  "storybook": "start-storybook -p 7007",
  "android": "react-native run-android",
  "ios": "react-native run-ios"
}

3. 让Babel识别环境变量

安装babel-plugin-transform-inline-environment-variables插件,确保Metro能正确读取环境变量:

npm install babel-plugin-transform-inline-environment-variables --save-dev

然后在babel.config.js里添加插件配置:

module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  plugins: [
    ['transform-inline-environment-variables', {
      "include": ["STORYBOOK_ENABLED"]
    }]
  ]
};

切换步骤

  • 第一次只需要构建一次应用:npm run android(之后再也不用重新执行这个命令)
  • 切换到主应用:停止当前Metro服务,运行npm run start,然后在模拟器里摇一摇设备选择「Reload」
  • 切换到Storybook:停止当前Metro服务,运行npm run start:storybook,同时启动Storybook UI服务npm run storybook,最后模拟器摇一摇Reload即可

方法二:开发环境添加切换按钮(更灵活)

如果觉得每次重启Metro麻烦,可以在App里加一个仅开发环境可见的切换按钮,不用重启服务就能切换:

修改App.js

import React, { useState } from 'react';
import { View, Button, StyleSheet } from 'react-native';
// 把原主应用内容抽成单独组件
import MainApp from './src/MainApp';
import StorybookUI from './storybook';

export default function App() {
  const [useStorybook, setUseStorybook] = useState(false);

  // 只在开发环境显示切换按钮
  if (__DEV__) {
    return (
      <View style={styles.container}>
        <Button
          title={useStorybook ? '切换到主应用' : '切换到Storybook'}
          onPress={() => setUseStorybook(!useStorybook)}
        />
        {useStorybook ? <StorybookUI /> : <MainApp />}
      </View>
    );
  }

  // 生产环境直接加载主应用
  return <MainApp />;
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    paddingTop: 20,
  },
});

使用方式

  • 构建一次应用后,打开App就能看到切换按钮
  • 点击按钮后,选择「Reload」或者开启Hot Reload,就能直接切换到对应的模式,完全不用重启Metro或重新构建

为什么之前需要重新构建?

之前的方式相当于把Storybook和主应用当成了两个独立的构建目标,每次切换都需要重新打包入口代码。而上面的方案是让它们共享同一个构建包,通过动态加载逻辑来切换,所以只需要一次构建就够了。

内容的提问来源于stack exchange,提问作者glocore

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:18:06