storybookjs / react-native

📓 Storybook for React Native!
https://storybook.js.org
MIT License
996 stars 141 forks source link

Absolute path module resolution failed #504

Closed neyosoft closed 11 months ago

neyosoft commented 11 months ago

Describe the bug When I set up absolute path resolution for my RN project using this babel configuration at the base of my React Native CLI project

babel.config.js

module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  plugins: [
    [
      'module-resolver',
      {
        root: ['./src'],
        extensions: ['.ios.js', '.android.js', '.js', '.ts', '.tsx', '.json'],
        alias: {
          '@components': './src/components',
        },
      },
    ],
  ],
};

tsconfig.json

{
  "extends": "@tsconfig/react-native/tsconfig.json",
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "*": ["src/*"],
      "@components/*": ["src/components/*"]
    }
  }
}

Storybook is unable to resolve my module

To Reproduce Steps to reproduce the behavior:

  1. Setup a fresh RN CLI Project
  2. Create a babel.config.js file to setup the absolute path
  3. Import any of your modules using an absolute path e.g import theme from 'theme'
  4. Observe the error similar to my screenshot

Expected behavior Storybook should be able to resolve the module path

Screenshots

Screenshot 2023-08-09 at 11 44 54 PM

Code snippets import {colors} from 'theme';

System: Environment Info:

System: OS: macOS 13.5 CPU: (10) x64 Apple M1 Pro Binaries: Node: 16.19.1 - ~/.nvm/versions/node/v16.19.1/bin/node Yarn: 1.22.19 - /usr/local/bin/yarn npm: 8.19.3 - ~/.nvm/versions/node/v16.19.1/bin/npm Browsers: Chrome: 115.0.5790.170 Safari: 16.6 npmPackages: @storybook/addon-actions: ^6.5.16 => 6.5.16 @storybook/addon-controls: ^6.5.16 => 6.5.16 @storybook/addon-ondevice-actions: ^6.5.6 => 6.5.6 @storybook/addon-ondevice-controls: ^6.5.6 => 6.5.6 @storybook/react-native: ^6.5.6 => 6.5.6

Additional context Module absolute path resolution

dannyhw commented 11 months ago

rn storybook doesn't effect your aliases... you should check that this works in the project normally.

neyosoft commented 11 months ago

Thank you so much for your feedback @dannyhw The aliases are working fine when I started the app normally.

I added the theme alias

babel.config.js

module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  plugins: [
    [
      'module-resolver',
      {
        root: ['./src'],
        extensions: ['.ios.js', '.android.js', '.js', '.ts', '.tsx', '.json'],
        alias: {
          '@theme': './src/theme',
          '@components': './src/components',
        },
      },
    ],
  ],
};

But am still getting this error

Screenshot 2023-08-10 at 12 50 21 PM

Please you can reproduce this issue with the repository

To start up storybook

yarn storybook-metro
yarn ios:dev
dannyhw commented 11 months ago

The problem is that you're using the two metro configs and so for one of the entry points the path is wrong

dannyhw commented 11 months ago

I've been suggesting this approach instead https://github.com/storybookjs/react-native/discussions/494

neyosoft commented 11 months ago

Wow... That sounds great.

But since the reference discussion used expo environment variables, how can I get an environment variable with RN CLI into the Babel config?

I used react-native-config with my application. Can I access the environment variables inside babel.config.js?

What other options do I have with RN CLI?

Thank you so much for your response.

dannyhw commented 11 months ago

you don't need any special config you can just write it like

MY_ENV_VAR=true yarn start

Then it should get loaded into the context of metro and babel.

It won't be in your app bundle though unless you use a babel plugin or something. However that shouldn't matter since all you need to do is change the source ext property in metro based on the env variable. You shouldn't need to adjust your aliases or babel config if you change your setup to use this strategy.

neyosoft commented 11 months ago

Thank you so much for your response @dannyhw. That option works perfectly.

I was able to confirm/debug that sourceExts was added to the final configuration and my App.storybook.tsx was picked up correctly. But now, am getting Unhandled JS Exception: Maximum call stack size exceeded when I tried to startup storybook.

Note: the app works normally if I start up Metro with react-native start

Here is my updated bable.config.js

const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');

const defaultConfig = getDefaultConfig(__dirname);

const storybookSourceExt =
  process.env.STORYBOOK_VARIANT === 'true' ? ['storybook.tsx'] : [];

const config = {
  resolver: {
    sourceExts: [...storybookSourceExt, ...defaultConfig.resolver.sourceExts],
    resolverMainFields: ['react-native', 'browser', 'main'],
  },
};

module.exports = mergeConfig(defaultConfig, config);

I am getting an Unhandled JS Exception: Maximum call stack size exceeded

Screenshot 2023-08-10 at 5 01 33 PM

Here is my current repository with all my changes: https://github.com/neyosoft/storybook

dannyhw commented 11 months ago

you're missing sbmodern in your metro config

resolverMainFields: ['sbmodern','react-native', 'browser', 'main'],
neyosoft commented 11 months ago

Great. it's working now on RN 0.72.3. Thank you so much @dannyhw for all your help. I really appreciate your effort.

I don't know if you mind me raising a PR with my babel.config.js configuration for folks using the latest RN version. That could have saved me hours of time trying to figure it out myself.

dannyhw commented 11 months ago

No problem, happy that you got it all working 🙂 .

Not sure where the code would go, aliases are not a storybook specific thing, its more of a react native setup thing.

It might make more sense to write a blog post if you want to share your setup with people because you can better explain the reasoning etc.

neyosoft commented 11 months ago

Sure. That would help. I'll work on that.

Thank you once again