storybookjs / builder-vite

A builder plugin to run and build Storybooks with Vite
MIT License
891 stars 107 forks source link

[Bug] - Vite transforming of stories is slow or hangs #577

Open visualjeff opened 1 year ago

visualjeff commented 1 year ago

What version of vite are you using?

4.3.8

System info and storybook versions

System: OS: macOS 13.3.1 CPU: (10) arm64 Apple M1 Max Binaries: Node: 18.4.0 - ~/.nvm/versions/node/v18.4.0/bin/node npm: 8.12.1 - ~/.nvm/versions/node/v18.4.0/bin/npm Browsers: Chrome: 113.0.5672.126 Edge: 111.0.1661.62 Safari: 16.4 npmPackages: @storybook/addon-a11y: ^7.0.12 => 7.0.12 @storybook/addon-actions: ^7.0.12 => 7.0.12 @storybook/addon-essentials: ^7.0.12 => 7.0.12 @storybook/addon-interactions: ^7.0.12 => 7.0.12 @storybook/addon-jest: ^7.0.12 => 7.0.12 @storybook/addon-links: ^7.0.12 => 7.0.12 @storybook/addon-styling: ^1.0.8 => 1.0.8 @storybook/blocks: ^7.0.12 => 7.0.12 @storybook/react: ^7.0.12 => 7.0.12 @storybook/react-vite: ^7.0.12 => 7.0.12 @storybook/testing-library: ^0.0.14-next.2 => 0.0.14-next.2

Describe the Bug

We have two Storybook 7 / Vite projects. One builds and renders but it takes some time. The other one just hangs and never recovers. The only difference between the two is the complexity of the stories. The project with the more complex stories just hangs. When running storybook build the project gets stuck with transforming and just hangs.

@storybook/cli v7.0.12

info => Cleaning outputDir: /Users/XXXXXX/Documents/ADO/forge.XXXXXX.web/docs/forge-digital-components
(node:67032) ExperimentalWarning: The Fetch API is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
info => Loading presets
info => Building manager..
info => Manager built (92 ms)
info => Copying static files: /Users/XXXXXX/Documents/ADO/forge.XXXXXX.web/node_modules/@storybook/manager/static at /Users/XXXXXX/Documents/ADO/forge.XXXXXX.web/docs/forge-digital-components/sb-common-assets
info => Copying static files: /Users/XXXXXX/Documents/ADO/forge.XXXXXX.web/packages/forge-digital-components/public at /Users/XXXXXX/Documents/ADO/forge.XXXXXX.web/docs/forge-digital-components/
vite v4.3.8 building for production...

./sb-common-assets/fonts.css doesn't exist at build time, it will remain unchanged to be resolved at runtime
transforming (85) src/components/Product/Swatch/index.jsx

Here is our main.js

import { mergeConfig } from 'vite';

/** @type { import('@storybook/react-vite').StorybookConfig } */
const config = {
  staticDirs: ['../public'],
  stories: [
    '../src/components/**/*.stories.@(js|jsx|ts|tsx)',
  ],
  addons: [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/addon-interactions",
    "@storybook/addon-styling",
    '@storybook/addon-a11y',
    '@storybook/addon-jest'
  ],
  framework: {
    name: "@storybook/react-vite",
    options: {},
  },
  async viteFinal(config) {
    // Merge custom configuration into the default config
    return mergeConfig(config, {
      // Add storybook-specific dependencies to pre-optimization
      optimizeDeps: {
        include: [
          '@storybook/addon-links',
          '@storybook/addon-essentials',
          '@storybook/addon-interactions',
          '@storybook/addon-styling',
          '@storybook/addon-a11y',
          '@storybook/addon-jest',
        ],
      },
    });
  },
  docs: {
    autodocs: true,
  },
};
export default config;

Our preview.jsx

import React from 'react';
import '../../forge-components/src/global/scss/style.scss';
import { CssBaseline, ThemeProvider } from "@mui/material";
import { withThemeFromJSXProvider } from "@storybook/addon-styling";
import { MuiXXXXXTheme } from '@xxxxxlabs/forge-components';

export const decorators = [
  withThemeFromJSXProvider({
    themes: { MuiXXXXXTheme },
    Provider: ThemeProvider,
    GlobalStyles: CssBaseline,
  }),
];

/** @type { import('@storybook/react').Preview } */
const preview = {
  parameters: {
    actions: { argTypesRegex: "^on[A-Z].*" },
    controls: {
      matchers: {
        color: /(background|color)$/i,
        date: /Date$/,
      },
    },
  },
};

export default preview;
  1. How can I debug or view what is going on in the transforming process?
  2. Any Vite for Storybook 7 tips to improve the performance of this transforming process?
  3. Has anyone else experienced this slow or hanging behavior?

Thank you.

Link to Minimal Reproducible Example

No response

Participation

IanVS commented 1 year ago

Can you check what version of @joshwooding/vite-plugin-react-docgen-typescript is installed? (npm ls @joshwooding/vite-plugin-react-docgen-typescript)

Aside from that, Vite is known to run out of memory when building, so I'd suggest increasing the memory available to node using something like NODE_OPTIONS="--max-old-space-size=6144".

visualjeff commented 1 year ago

Here is the version info:

"name": "@joshwooding/vite-plugin-react-docgen-typescript", "version": "0.2.1",

visualjeff commented 1 year ago

There is a 0.2.3 version of @joshwooding/vite-plugin-react-docgen-typescript. I could force the use of a newer version?

IanVS commented 1 year ago

Version 0.2.2 had a perf regression, but 0.2.1 should be fine. Did you try increasing the available memory to node?

IanVS commented 1 year ago

The other thing you can do is take a look at the network tab when loading a story in dev mode, and see if unexpected packages are being loaded, for example through index.js files.

visualjeff commented 1 year ago

I did bump the memory for node. After about 28 minutes the transforming blew chunks and did point out an error with an icon we were trying to import. The developer was trying to import it using the wrong name. I corrected this and kicked off another build-storybook. Right now its hanging on transforming (72) ../../node_modules/date-fns/esm/locale/index.js. But I'll give it time. I'm running this on a M1-Max with 64 gigs of memory.

visualjeff commented 1 year ago

Ok. It finished. Took about 15 minutes.

IanVS commented 1 year ago

How many stories do you have, and do you use barrel imports (index files)?

visualjeff commented 1 year ago

10 stories total and yes we do use barrel imports.

The transforming process takes a long time with the following dependencies:

date-fns prop-types @storybook/react-dom-shim html-tags

IanVS commented 1 year ago

I also use a few functions from date-fns, have 900 stories on 183 components, and my build takes 45 seconds on an older mac.

Maybe you can create a minimal reproduction that I can look into?

visualjeff commented 1 year ago

We'll I must doing something wrong. Lol. I'll see what I can do to create a repo you can examine.

When it does complete it provides these suggestions:

(!) Some chunks are larger than 500 kBs after minification. Consider:
- Using dynamic import() to code-split the application
- Use build.rollupOptions.output.manualChunks to improve chunking: https://rollupjs.org/configuration-options/#output-manualchunks
- Adjust chunk size limit for this warning via build.chunkSizeWarningLimit.
visualjeff commented 1 year ago

I'm testing with no stories.

Hangs on transforming @storybook/addon-outline/dist/chunk-2DMOCDBJ.mjs

visualjeff commented 1 year ago

I don't know if I mentioned it but we're using an NPM monorepo. So our node_modules is located outside of the project.

IanVS commented 1 year ago

Does it speed up if you disable docgen? That will help narrow down where the problem is happening.

Put this in your storybook config:

typescript: {
    reactDocgen: false,
  }
visualjeff commented 1 year ago

It speeds up but still hangs for a long time on: transforming (48) ../../node_modules/estraverse/estraverse.js

Is the issue the monorepo structure?

IanVS commented 1 year ago

I'm not sure. You could try moving storybook to one of the packages in the monorepo and see if that makes a big difference.

Coming up with documentation for best practices for monorepos is on the team's radar, you can give an upvote to https://github.com/storybookjs/storybook/issues/22271 if you think that'd be useful.

visualjeff commented 1 year ago

Moving the code out of the monorepo did make a difference. Build completed in 9 seconds. I wonder if its the linked dependencies that might be the issue?

visualjeff commented 1 year ago

After setting a sampleStorybook within our monorepo project it looks like its our linked dependencies from our other packages within the monorepo that are slowing thing things down.

IanVS commented 1 year ago

@visualjeff one thing I forgot to mention that you could try, is using vite's preserveSymlinks option: https://vitejs.dev/config/shared-options.html#resolve-preservesymlinks. Otherwise, vite will treat all of your components as external files, and will perform its dependency optimizations on it (converting cjs to esm, etc).

ahnpnl commented 1 year ago

I want to share a workaround to improve build performance which I'm doing in my project.

Project structure

My project has this structure:

│   .storybook // storybook config
│   assets // global style files, translation files
|   src // application codes
│   stories // story files

Project conventions

My team only wants to create story files for reusuable UI components, which means the components that reflect design system only and these components have no dependencies on things like APIs or translation.

Introducing workaround

In .storybook/main.ts I did the following

import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';

import { globSync } from 'glob';
import type { OutputPlugin } from 'rollup';

import { APP_BUILD_PLUGINS } from '../vite.config';

const storybookConfig = {
    // ...
    viteFinal(config) {
        const projectDirPath = join(dirname(fileURLToPath(import.meta.url)), '..');
        const filePathsToExclude = globSync(['src/**/*.{ts,tsx,gql}', 'assets/**/*.{json,scss}']).map((filePath) =>
            join(projectDirPath, filePath),
        );

        return {
            ...config,
            build: {
                ...config.build,
                rollupOptions: {
                    ...config.build?.rollupOptions,
                    external: [...(config.build?.rollupOptions?.external as string[]), ...filePathsToExclude],
                },
            },
            plugins: config.plugins?.filter(
                (plugin) =>
                    !APP_BUILD_PLUGINS.map((buildPlugin) => buildPlugin.name).includes((plugin as OutputPlugin).name),
            ),
        };
    },
};

export default storybookConfig;

Investigation and findings

What I've discovered was: when serving or building Storybook, Vite will try to:

Benefits of the workaround

I hope this helps!

lee-borsboom commented 1 year ago

Any traction on this one? I'm experiencing what sounds like the same issue, also in a monorepo. Storybook build takes about 12mins for me.

samesfahani-tuplehealth commented 1 year ago

How many stories do you have, and do you use barrel imports (index files)?

Could you elaborate on this one? Are barrel files not recommended or supported? We use them quite extensively.

IanVS commented 1 year ago

Barrel files are generally not recommended, due to the potential for increasing your bundle size if tree-shaking is not working perfectly. And they can also cause problems with vite's HMR, see https://github.com/vitejs/vite-plugin-react-swc/discussions/41#discussioncomment-4661641.

There's a plugin that you can try out, which may help: https://github.com/vitejs/vite/issues/8237#issuecomment-1285887097

satanshiro commented 7 months ago

I am experiencing the same problem I tried the above solution but does not work started happening in an nx monorepo, typescript with vite storybook build just hangs. node version 20.11.0 "@storybook/addon-essentials": "8.0.0-beta.5", "@storybook/addon-interactions": "8.0.0-beta.5", "@storybook/core-server": "8.0.0-beta.5", "@storybook/react": "8.0.0-beta.5", "@storybook/react-vite": "8.0.0-beta.5", "typescript": "^5.2.2", "vite": "5.1.4", "vite-plugin-dts": "~3.7.3", "vite-tsconfig-paths": "^4.3.1", "vitest": "1.3.1" happens also on latest and non beta version

satanshiro commented 7 months ago

I am experiencing the same problem I tried the above solution but does not work started happening in an nx monorepo, typescript with vite storybook build just hangs. node version 20.11.0 "@storybook/addon-essentials": "8.0.0-beta.5", "@storybook/addon-interactions": "8.0.0-beta.5", "@storybook/core-server": "8.0.0-beta.5", "@storybook/react": "8.0.0-beta.5", "@storybook/react-vite": "8.0.0-beta.5", "typescript": "^5.2.2", "vite": "5.1.4", "vite-plugin-dts": "~3.7.3", "vite-tsconfig-paths": "^4.3.1", "vitest": "1.3.1" happens also on latest and non beta version

I tried a lot of different things also reverting vite with no success, if i run verbose i see the command hangs on [Nx Vite TsPaths] Resolved vite/preload-helper.js to undefinedor so it seems

jonfrost43 commented 7 months ago

@satanshiro I had the same issue in an Nx monorepo in the last few days. The Storybook build task with vite@5.1.3 started hanging in CI and then locally like this:

[Nx Vite TsPaths] Resolved vite/preload-helper.js to undefined
transforming (554) ../../node_modules/@storybook/addon-docs/node_modules/@storybook/components/dist/WithTooltip-V3YHNWJZ.mjs

I tried several fixes mentioned above, but saw no improvement or error reported.

Eventually I upgraded my Storybook config to use the @nx/storybook plugin and got this error back:

[Nx Vite TsPaths] Resolved vite/preload-helper.js to undefined
x Build failed in 1.08s
=> Failed to build the preview
Error: Unexpected early exit. This happens when Promises returned by plugins cannot resolve. Unfinished hook action(s) on exit:
(vite:esbuild) transform "./.storybook/preview.ts"
(vite:esbuild) transform "./src/lib/vitelib.stories.tsx"

So I tried removing Vite plugins and found that vite-plugin-dts was the problem. So I filtered it out in .storybook/main.ts:

viteFinal: (config) => {
    const filteredPlugins = config.plugins?.filter(plugin => plugin?.name !== "vite:dts") ?? [];
    return { ...config, plugins: filteredPlugins };
},

This worked for my Nx 18 library with Storybook. Hope it's helpful for you.

adamwdennis commented 6 months ago

Upgrading to vite 5.1.6 has fixed this issue for me.

zeroliu commented 1 month ago

I'm on storybook 8.2.9 and vite 5.4.2. The latest storybook version builds much slower than storybook 7.6.16, and it runs out of memory even with --max_old_space_size=8192. It gets much faster after turning off reactDocgen and the memory issue goes away. I was using reactDocgen without issues in 7.6.16.

Please feel free to let me know if there is any detailed logs that I can provide to help with debugging. Thanks!