DEV Community

How to swap between React Native Storybook and your app

Danny on February 06, 2023

EDIT: I have recently updated this guide to show a few different approaches I will update further if I find better solutions Storybook in react na...
Collapse
 
astriskit profile image
H S

Hi there. Came across this while setting storybook for an expo project. Ended it with manually (script-able) updating the main value in the package.json along with having the flag indicating the storybook-enabled through env-vars.

The app is expo-router based so main's value becomes expo-router/entry whereas the storybook-setup becomes node_modules/expo/AppEntry.js.

Nicely compiled guide. Cheers.

Collapse
 
dmahajan980 profile image
Divyanshu Mahajan • Edited

Thanks for this article! I wish we could specify the storybook entry file though a field in package.json or storybook config file.

Collapse
 
dannyhw profile image
Danny • Edited

No problem :). Yes I have also been wishing for that, unfortunately I didn’t find a way on expo yet, but I have another guide on how you can do that for rn-cli using two metro configs but its a bit more involved.

In fact you can use the main field in package.json to specify your entry point when using expo but its very manual.

Collapse
 
dannyhw profile image
Danny

I updated this post with a new approach that I think matches what you are looking for!

Collapse
 
flexbox profile image
David Leuliette 🤖

Awesome article thank you Danny 🚀

Collapse
 
alexischappron profile image
Alexis C

Interesting,
Is there any cons to using metro's sourceExts to differenciate the regular entryPoint index.ts and the storybook one index.storybook.ts ?
I think it's a nice way to be sure that no storybook code get shipped in the release version, it also allow us to mock other files if needed.

Collapse
 
dannyhw profile image
Danny

That sounds interesting, do you have an example? I would love to add an example like this to the post.

Collapse
 
alexischappron profile image
Alexis C

Yep, I did a repo you can check if you want, everything should work github.com/ACHP/AwesomeStorybookPr...

Thread Thread
 
dannyhw profile image
Danny

Hey sorry it took me a while to get to this but this is a really nice solution. The only potential downside is the user should understand that .storybook.tsx would have special meaning throughout the project.

Nice suggestion! I'll add it :)

Collapse
 
ederbiason profile image
Eder Henrique Biason de Oliveira

I'm receiving the following error when I try to run 'yarn storybook':

sb-rn-get-stories && STORYBOOK_ENABLED='true' expo start
'STORYBOOK_ENABLED' is not recognized as an internal or external command,
operable program or batch file.

Collapse
 
dannyhw profile image
Danny

if you are using windows STORYBOOK_ENABLED='true' will throw an error, you can use cross-env to make it work like cross-env STORYBOOK_ENABLED='true' expo start

Collapse
 
ederbiason profile image
Eder Henrique Biason de Oliveira

thank you!! helped me a lot.. nice article btw

Collapse
 
_zubko profile image
Alexander Zubko

Interesting tip, but you may end up with Storybook code in your production bundle. I think Metro would just crawl all files starting from index and it will look for require calls and pack all your imports into the bundle at compile time, when it doesn’t know if that if condition with env var resolves to true or false. Unless someone coded intentionally the support to ignore requires inside the if(__DEV__).

I think it is safer to load Storybook from a separate index.storybook.js entry point or smth to not even have a chance of that code to be included to the main bundle. That’s of course is very doable for a regular RN app, but I’ve never used Storybook with Expo Managed though to try if it’s possible there.

Collapse
 
dannyhw profile image
Danny

Whilst this is possible I'm not sure thats the case until I've fully tested it. I recommend anyone to also test this kind of thing before you copy code into your production project.

I will be following up this post soon with some testing around the bundle and whether this really makes a difference.

Collapse
 
dannyhw profile image
Danny • Edited

Thanks for your feedback, I've updated the guide with an alternative approach using an index.storybook.js like your suggested.

Collapse
 
sebastienlorber profile image
Sebastien Lorber

Useful trick.

Little concern: will the Storybook be appropriately tree-shaked from the prod JS bundle when reading from expoConfig? I'm not sure.

Collapse
 
dannyhw profile image
Danny • Edited

Hey Sebastian, my understanding is that it shouldn't be included since it uses an inline require, but I could be wrong.

I think you could also use a lazy import like AppEntryPoint = React.lazy(() => import('./.storybook')); which would potentially be safer.

Then you can also put __DEV__ && storybookEnabled to be sure you don't execute that code outside of a dev environment.

Generally I use storybook as a separate app/package in a mono repo so my projects don't have this problem, so I'll have to double check this and make sure.

Collapse
 
dannyhw profile image
Danny • Edited

@sebastienlorber thanks for your feedback I've updated the guide to use a different entry point instead of expo constants

Collapse
 
Sloan, the sloth mascot
Comment deleted
Collapse
 
lucksp profile image
Philip Lucks

Is there a way we can use the expo-dev-menu to toggle the App & Storybook?

Collapse
 
dannyhw profile image
Danny