storybookjs / addon-react-native-web

Build react-native-web projects in Storybook for React
MIT License
83 stars 22 forks source link

[Bug]: Storybook imports extra unnecessary files #77

Open ChrisEdson opened 11 months ago

ChrisEdson commented 11 months ago

Describe the bug

Storybook imports random files when used with @storybook/addon-react-native-web.

This causes the build to fail.

An example repository can be found here and the failing build here.

You can see the error is:

ERROR in ./node_modules/react-native/Libraries/StyleSheet/processColor.js 1:442-497
Module not found: Error: Can't resolve './PlatformColorValueTypes' in '/home/runner/work/storybook-test/storybook-test/node_modules/react-native/Libraries/StyleSheet'
 @ ./node_modules/@react-native-community/art/lib/helpers.js 1:715-772
 @ ./node_modules/@react-native-community/art/lib/Shape.js 1:930-950
 @ ./node_modules/@react-native-community/art/lib/index.js 1:1524-1542
 @ ./node_modules/react-native-progress/Circle.js 1:1329-1367
 @ ./node_modules/react-native-progress/index.js 1:631-650
 @ ./src/components/ImageProgress/ImageProgress.tsx 1:105-137
 @ ./src/ lazy ^\.\/.*$ namespace object ./components/ImageProgress/ImageProgress.tsx ./components/ImageProgress/ImageProgress
 @ ./storybook-stories.js 1:567-597
 @ ./storybook-config-entry.js 1:158-191 1:983-1115

This is a typical transpilation error that you see with react-native-web - but the <ImageProgress /> component is not being imported in to any of the stories (of which there is only one: https://github.com/ChrisEdson/storybook-test/blob/main/src/components/ui/DesignSystemHeadlineFive.stories.tsx).

I'm really confused by this. The stories property in main.js only specifies stories to be included:

stories: ["../src/**/*.stories.@(js|jsx|ts|tsx)"],

To Reproduce

https://github.com/ChrisEdson/storybook-test

System

Storybook Environment Info:

  System:
    OS: macOS 14.0
    CPU: (8) arm64 Apple M1 Pro
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.5.1 - ~/.nvm/versions/node/v20.5.1/bin/node
    npm: 9.8.0 - ~/.nvm/versions/node/v20.5.1/bin/npm <----- active
  Browsers:
    Chrome: 119.0.6045.159
    Safari: 17.0
  npmPackages:
    @storybook/addon-react-native-web: 0.0.21 => 0.0.21
    @storybook/react: ^7.5.3 => 7.5.3
    @storybook/react-webpack5: ^7.5.3 => 7.5.3
    storybook: ^7.5.3 => 7.5.3
shilman commented 10 months ago

@tmeasday do you know why this might happen? Does webpack have problems tree-shaking due to the glob-to-regex trick that we do? I looked through the addon-react-native-web code and nothing jumped out at me there.

tmeasday commented 10 months ago

I'm really unsure about this one too. Here's the contents of storybook-stories.js as logged by node:

const pipeline = (x) => x();

const importers = [
  async (path) => {
    if (!/^\.[\\/](?:src(?:\/(?!\.)(?:(?:(?!(?:^|\/)\.).)*?)\/|\/|$)(?!\.)(?=.)[^/]*?\.stories\.(js|jsx|ts|tsx))$/.exec(path)) {
      return;
    }

    const pathRemainder = path.substring(6);
    return import(
      /* webpackChunkName: "[request]" */
      /* webpackInclude: /(?:\/src(?:\/(?!\.)(?:(?:(?!(?:^|\/)\.).)*?)\/|\/|$)(?!\.)(?=.)[^/]*?\.stories\.(js|jsx|ts|tsx))$/ */
      './src/' + pathRemainder
    );
  }

];

export async function importFn(path) {
  for (let i = 0; i < importers.length; i++) {
    const moduleExports = await pipeline(() => importers[i](path));
    if (moduleExports) {
      return moduleExports;
    }
  }
}

You can see the webpackInclude directive that should stop the ImageProgress file from being imported. This is code that we've had for a while and the webpack version seems fine. Maybe this is happening in general but people's other src files aren't causing problems?


> re = /(?:\/src(?:\/(?!\.)(?:(?:(?!(?:^|\/)\.).)*?)\/|\/|$)(?!\.)(?=.)[^/]*?\.stories\.(js|jsx|ts|tsx))$/
/(?:\/src(?:\/(?!\.)(?:(?:(?!(?:^|\/)\.).)*?)\/|\/|$)(?!\.)(?=.)[^/]*?\.stories\.(js|jsx|ts|tsx))$/
> re.exec('./src/foo.stories.ts')
[
  '/src/foo.stories.ts',
  'ts',
  index: 1,
  input: './src/foo.stories.ts',
  groups: undefined
]
> re.exec('./src/components/ImageProgress/ImageProgress.tsx')
null
tmeasday commented 10 months ago

I just tried something similar in a sandbox. No error if I add src/stories/Random.ts, error if I add src/stories/Random.stories.ts. The file was just:

import 'something wrong';

The error I got was:

ERROR in ./src/stories/Random.stories.ts 1:0-25
Module not found: Error: Can't resolve 'something wrong' in '/Users/tom/GitHub/storybookjs/storybook/sandbox/nextjs-default-ts/src/stories'
 @ ./src/ lazy ^\.\/.*$ include: (?:\/src(?:\/(?%21\.)(?:(?:(?%21(?:^%7C\/)\.).)*?)\/%7C\/%7C$)(?%21\.)(?=.)[^/]*?\.stories\.(js%7Cjsx%7Cmjs%7Cts%7Ctsx))$ chunkName: [request] namespace object ./stories/Random.stories.ts ./stories/Random.stories
 @ ./storybook-stories.js 23:11-27:5
 @ ./storybook-config-entry.js 6:0-50 25:21-29 28:2-31:4 28:58-31:3 30:31-39

I have webpack@5.89.0 which is the same version as in the repro above 🤔

Notice the error in the repro says:

 @ ./src/ lazy ^\.\/.*$ namespace object ./components/ImageProgress/ImageProgress.tsx ./components/ImageProgress/ImageProgress
 @ ./storybook-stories.js 1:567-597
 @ ./storybook-config-entry.js 1:158-191 1:983-1115

I'm not sure why the regexp is missing the include there?

I wonder if something in the build process is stripping comments. Notice there's no chunkName either.

tmeasday commented 10 months ago

Maybe it's something in @storybookjs/addon-react-native-web, specifically in https://github.com/storybookjs/addon-react-native-web/blob/main/src/webpack.ts somewhere?

When I no-oped that webpackFinal I get this error, which seems to confirm it is the config (notice the include directive in the stack trace):

ERROR in ./node_modules/react-native/index.js 14:7
Module parse failed: Unexpected token (14:7)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
|
| // Components
> import typeof AccessibilityInfo from './Libraries/Components/AccessibilityInfo/AccessibilityInfo';
| import typeof ActivityIndicator from './Libraries/Components/ActivityIndicator/ActivityIndicator';
| import typeof Button from './Libraries/Components/Button';
 @ ./src/components/ui/DesignSystemHeadlineFive.tsx 1:102-125
 @ ./src/components/ui/DesignSystemHeadlineFive.stories.tsx 1:152-189
 @ ./src/ lazy ^\.\/.*$ include: (?:\/src(?:\/(?%21\.)(?:(?:(?%21(?:^%7C\/)\.).)*?)\/%7C\/%7C$)(?%21\.)(?=.)[^/]*?\.stories\.(js%7Cjsx%7Cts%7Ctsx))$ chunkName: [request] namespace object ./components/ui/DesignSystemHeadlineFive.stories.tsx ./components/ui/DesignSystemHeadlineFive.stories
 @ ./storybook-stories.js 10:11-14:5
 @ ./storybook-config-entry.js 6:0-50 25:21-29 28:2-31:4 28:58-31:3 30:31-39

As further evidence - if I make the main.js:stories match no stories:

shilman commented 10 months ago

Hmm @dannyhw I wonder if the include logic here is somehow causing unnecessary files to be processed by webpack. https://github.com/storybookjs/addon-react-native-web/blob/main/src/webpack.ts#L68-L88

Moving this issue to the addon-react-native-web repo...

brenodt commented 6 months ago

Documenting here, as it took me ages to get this working on my project, and it might help someone trying just to get the integration off the ground until this gets fixed.

My use-case is simple, I want to start adding stories little by little in a very well-established project, full of dependencies. Trying to follow the README got me here, as I had hundreds of Module not found: Error: Can't resolve [...] errors.

I only have a single Button.stories.tsx file, which doesn't import nothing but:

import { View } from 'react-native';
import type { Meta, StoryObj } from '@storybook/react';
import { MyButton } from './Button';

(it's the boilerplate example generated by storybook/react-native)

Manually importing the stories gets rid of the errors - which seems to indicate the issue lies in the lazy loading:

import type { StorybookConfig } from '@storybook/react-webpack5';

const config: StorybookConfig = {
  stories: [
    // Got rid of these:
    // '../src/**/*.mdx',
    // '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)',

    // Added the story manually
    '../src/components/Button/Button.stories.tsx',
  ],
  // the rest remains the same...
};

export default config;
robertwt7 commented 2 months ago

I am also having the same issue here. Storybook is importing all of my other components that are not even imported in the stories. Causing so many issues.. on top of that, the example linked in the repo from dannyhw/expo-storybook-starter for react-native-web also doesn't seem to work for me.

I have to install @storybook/addon-styling-webpack for some reason to make it work..