rspack-contrib / storybook-rsbuild

Storybook builder and frameworks powered by Rsbuild.
MIT License
60 stars 3 forks source link
react rsbuild rspack storybook vue

Storybook Rsbuild

Storybook × Rsbuild

latest version NPM downloads per month license

The repository contains the Storybook Rsbuild builder and framework integrations for UI frameworks.

package description
storybook-builder-rsbuild Rsbuild powered builder for Storybook
storybook-react-rsbuild React integration for Storybook with Rsbuild builder
storybook-vue3-rsbuild Vue 3 integration for Storybook with Rsbuild builder

Usage

[!IMPORTANT]
Peer dependencies requirements:

  • @rsbuild/core >= 1.0.1-beta.14: Rsbuild is about to release version 1.0.0, and the current alpha version is already very reliable. (check out Rsbuild's 1.0.0 breaking changes)
  • storybook >= 8.2.1: Storybook made some internal refactor in major version, 8.2.1 is tested out. (check out Storybook's release note for migrating from v7)

In Storybook v8, you don't need to manually install storybook-builder-rsbuild, it has been depended by the framework, such as storybook-react-rsbuild and storybook-vue3-rsbuild.

Use with React (in a existing Rsbuild project)

  1. Install React framework integration
    pnpm i storybook-react-rsbuild -D
  2. Change .storybook/main.js

    import { StorybookConfig } from 'storybook-react-rsbuild'
    
    const config: StorybookConfig = {
     framework: 'storybook-react-rsbuild',
     rsbuildFinal: (config) => {
       // Customize the final Rsbuild config here
       return config;
     },
    };
    
    export default config;

You're all set now. You could also check out the example in sandboxes/react-18 and use all other features listed in Storybook site.

Use with Vue 3 (in a existing Rsbuild project)

  1. Install Vue3 framework integration
    pnpm i storybook-vue3-rsbuild -D
  2. Change .storybook/main.js

    import { StorybookConfig } from 'storybook-vue3-rsbuild'
    
    const config: StorybookConfig = {
     framework: 'storybook-vue3-rsbuild',
     rsbuildFinal: (config) => {
       // Customize the final Rsbuild config here
       return config;
     },
    };
    
    export default config;

You're all set now. You could also check out the example in sandboxes/vue3-rsbuild and use all other features listed in Storybook site.

Builder options

rsbuildConfigPath

The builder will automatically load Rsbuild config file (e.g. rsbuild.config.js) in the project, though it may change some of the options in order to work correctly. It looks for the Rsbuild config in the CWD. If your config is located elsewhere, specify the path using the rsbuildConfigPath builder option:

// .storybook/main.mjs

const config = {
  framework: {
    name: 'storybook-react-rsbuild',
    options: {
      builder: {
        rsbuildConfigPath: '.storybook/customRsbuildConfig.js',
      },
    },
  },
}

export default config

lazyCompilation

Enables Rspack's experimental lazy compilation.

// .storybook/main.mjs

const config = {
  framework: {
    name: 'storybook-react-rsbuild',
    options: {
      builder: {
        lazyCompilation: true,
      },
    },
  },
}

export default config

environment

Rsbuild supports build with environment config. When there's not listed environment or only one environment, the builder will the default environment's config. If there're more than one environment, you must specify the environment with environment option to tell the builder which environment's config to use.

// .storybook/main.mjs

const config = {
  framework: {
    name: 'storybook-react-rsbuild',
    options: {
      builder: {
        environment: 'web-storybook',
      },
    },
  },
}

export default config

addonDocs

@storybook/addon-docs webpack options. The builder uses @storybook/addon-docs internally, and accepts the passing some options via addonDocs.

// .storybook/main.mjs
import remarkGfm from 'remark-gfm';

const config = {
  framework: {
    name: 'storybook-react-rsbuild',
    options: {
      builder: {
        addonDocs: {
          mdxPluginOptions: {
            mdxCompileOptions: {
              remarkPlugins: [remarkGfm],
            },
          },
        },
      },
    },
  },
}

export default config

Customize builder's Rsbuild config

You can also override the merged Rsbuild config:

// use `mergeRsbuildConfig` to recursively merge Rsbuild options
import { mergeRsbuildConfig } from '@rsbuild/core'

const config = {
  async rsbuildFinal(config, { configType }) {
    // Be sure to return the customized config
    return mergeRsbuildConfig(config, {
      // Customize the Rsbuild config for Storybook
      source: {
        alias: { foo: 'bar' },
      },
    })
  },
}

export default config

The rsbuildFinal function will give you config which is the combination of your project's Rsbuild config and the builder's own Rsbuild config. You can tweak this as you want, for example to set up aliases, add new plugins etc.

The configType variable will be either "DEVELOPMENT" or "PRODUCTION".

The function should return the updated Rsbuild configuration.

FAQ

How to Storybook to a subdirectory / subpath?

The default Vite and webpack builders in Storybook use relative paths for references, whereas Rsbuild does not recommend using relative paths for deployment (See the tips). Therefore, if you want to deploy Storybook on a sub-path such as https://example.com/sb-path, you can achieve this by configuring output.assetPrefix.

const config: StorybookConfig = {
  // --snip--
  rsbuildFinal: (config) => {
+   config.output ??= {}
+   config.output.assetPrefix = '/sb-path/'
    return config
  },
  // --snip--
}

Error caused by bundling unexpected files

[!NOTE] Rspack starts to support webpackInclude magic comment, this trouble won't exists since 0.0.7

Because Rspack temporarily does not support the webpackInclude magic comment, non-story files may be bundled, which could lead to build failures. These files can be ignored using rspack.IgnorePlugin (see exmaple https://github.com/rspack-contrib/storybook-rsbuild/issues/19).

// .storybook/main.js
import path from 'path'
import { mergeRsbuildConfig } from '@rsbuild/core'

export default {
  framework: 'storybook-react-rsbuild',
  async rsbuildFinal(config) {
    return mergeRsbuildConfig(config, {
      tools: {
        rspack: (config, { addRules, appendPlugins, rspack, mergeConfig }) => {
          return mergeConfig(config, {
            plugins: [
              new rspack.IgnorePlugin({
                checkResource: (resource, context) => {
                  // for example, ignore all markdown files
                  const absPathHasExt = path.extname(resource)
                  if (absPathHasExt === '.md') {
                    return true
                  }

                  return false
                },
              }),
            ],
          })
        },
      },
    })
  },
}

Roadmap

Features

Rspack support

Credits

Some code is copied or modified from storybookjs/storybook.

License

MIT