Giter Site home page Giter Site logo

rspack-contrib / storybook-rsbuild Goto Github PK

View Code? Open in Web Editor NEW
55.0 4.0 2.0 2.15 MB

Storybook builder and frameworks powered by Rsbuild.

License: MIT License

TypeScript 64.75% EJS 1.55% Handlebars 0.77% JavaScript 0.20% CSS 7.59% MDX 21.27% Vue 3.87%
react rsbuild rspack storybook vue

storybook-rsbuild's Introduction

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.0-alpha.9: 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

  • Type: string
  • Default: undefined

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

  • Type: boolean
  • Default: false

Enables Rspack's experimental lazy compilation.

// .storybook/main.mjs

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

export default config

environment

  • Type: string
  • Default: undefined

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

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.

Troubleshooting

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 #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

  • Support TS type check (fork-ts-checker-webpack-plugin) (supported in 0.0.4)
  • Support more frameworks (Preact / Svelte / vanilla html / Lit)

Rspack support

  • Support webpackInclude magic comment (supported in 0.0.7)
  • Support persistent cache
  • Support lazy compilation
  • Support virtual modules
  • Support module.unknownContextCritical
  • Support compilation.dependencyTemplates.set for react-docgen-typescript (supported in a workaround)

Credits

Some code is copied or modified from storybookjs/storybook.

License

MIT

storybook-rsbuild's People

Contributors

alcpereira avatar chenjiahan avatar fi3ework avatar tmkx avatar valentinpalkovic avatar wrose504 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

storybook-rsbuild's Issues

Very long compilation time and error "Conflict: Multiple assets emit different content to the same filename iframe.html" when source.entry is set in rsbuild config

I try to migrate from storybook/vite to storybook with rsbuild but I have a compilation error :

yarn run v1.22.22
$ cross-env NODE_OPTIONS=--max-old-space-size=8192 storybook dev -p 6006
storybook v8.2.2

info => Serving static files from ./.\public at /
info => Starting manager..
info => Starting preview..
info Addon-docs: using MDX3
start   Compiling...
info Using tsconfig paths for react-docgen
error   Compile error: 
Failed to compile, check the errors for troubleshooting.
× Conflict: Multiple assets emit different content to the same filename iframe.html

The error seems non blocking : after closing the overlay, the storybook page run normally

I googled that error but it seems related to webpack, I didn't find any hint

excerp of package.json :

"@rsbuild/core": "1.0.1-beta.1",
    "@rsbuild/plugin-eslint": "1.0.0",
    "@rsbuild/plugin-react": "1.0.1-beta.1",
    "@rsbuild/plugin-type-check": "1.0.1-beta.1",
    "@rsdoctor/rspack-plugin": "^0.3.7",
    "@storybook/addon-essentials": "8.2.2",
    "@storybook/addon-interactions": "8.2.2",
    "@storybook/addon-links": "8.2.2",
    "@storybook/addon-onboarding": "8.2.2",
    "@storybook/blocks": "8.2.2",
    "@storybook/react": "8.2.2",
    "@storybook/react-vite": "8.2.2",
    "@storybook/test": "8.2.2",
    "@storybook/test-runner": "0.19.0",
    "msw-storybook-addon": "2.0.3",
    "playwright": "1.45.1",
    "react-test-renderer": "18.3.1",
    "storybook": "8.2.2",
    "storybook-addon-manual-mocks": "1.0.4",
    "storybook-react-rsbuild": "0.0.7",
    "storybook-addon-remix-react-router": "3.0.0",
    "resolutions": {
       "@storybook/csf": "0.1.11"
    },

storybook config :

import { StorybookConfig } from 'storybook-react-rsbuild'
import { mergeRsbuildConfig } from '@rsbuild/core'

const config: StorybookConfig = {
  stories: [
    "../src/**/*.stories.@(ts|tsx)"
  ],
  addons: [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/addon-onboarding",
    "@storybook/addon-interactions",
    {
      name: "storybook-addon-manual-mocks/vite",
      options: {
        mocksFolder: "mocks",
      }
    },
    'storybook-addon-remix-react-router',
  ],
  framework: {
    name: 'storybook-react-rsbuild',
    options: {}
  },
  rsbuildFinal: (config) => {
    // see https://github.com/rspack-contrib/storybook-rsbuild#customize-the-rsbuild-config
    return mergeRsbuildConfig(config, {
      source: {
        include: [
          /node_modules[\\/]storybook-addon-remix-react-router[\\/]dist[\\/]index.js/
        ]
      }
    })
  },
  staticDirs: ['../public'],
  docs: {
    defaultName: "Docs",
    docsMode: false,
    autodocs: false,
  },
}

export default config

Can't resolve deps with @rsbuild/core 1.0.1-beta.10

When I try to add the dependency to a project that is using the latest published version of @rsbuild/core I'm getting an errror that it can't resovle the dependency:

-> % npm add -D storybook-react-rsbuild
npm error code ERESOLVE
npm error ERESOLVE unable to resolve dependency tree
npm error
npm error While resolving: [email protected]
npm error Found: @rsbuild/[email protected]
npm error node_modules/@rsbuild/core
npm error   @rsbuild/core@"^1.0.1-beta.10" from the root project
npm error
npm error Could not resolve dependency:
npm error peer @rsbuild/core@">= 1.0.0-alpha.9" from [email protected]
npm error node_modules/storybook-react-rsbuild
npm error   dev storybook-react-rsbuild@"*" from the root project
npm error
npm error Fix the upstream dependency conflict, or retry
npm error this command with --force or --legacy-peer-deps
npm error to accept an incorrect (and potentially broken) dependency resolution.

Fail to execute web worker

Reproduction

https://github.com/yf-yang/rsbuild-storybook-monorepo/tree/worker

cd packages/pkg1
pnpm i
pnpm storybook

Click any component (e.g. Button), open the browser console for error logs.

Check packages/pkg1/.storybook/test.ts and packages/pkg2/src/index.ts for code diff

Error message

Failed to execute 'importScripts' on 'WorkerGlobalScope': The script at 'http://localhost:6006/static/js/async/static/js/vendors-node_modules_pnpm_rspack_plugin-react-refresh_0_7_4_react-refresh_0_14_2_node_modules-9567b7.iframe.bundle.js' failed to load.

`public/index.html` gets copied instead of the Storybook template when building

When running storybook build, if there is an HTML template located at public/index.html, it is copied to the storybook-static instead of the correct storybook HTML entrypoint.

Example repo: https://github.com/Atmos4/rsbuild-storybook-demo/tree/public-index-faulty-copy
Branch: public-index-faulty-copy.

Example configuration:

export default defineConfig({
  plugins: [pluginReact()],
  html: {
    template: "./public/index.html",
  },
});

Expected behavior

The template file should be ignored. There shouldn't be any way to produce a corrupted storybook build.

Not working on Linux

Background

I'm trying to add storybook tests to the CI workflow, but the rsbuild crashes due to a port duplicate:

$ storybook dev -p 6006

=> Failed to build the preview
Error: Port "6006" is occupied, please choose another one.
    at getPort (./node_modules/.pnpm/@[email protected]/node_modules/@rsbuild/core/dist/index.cjs:2611:17)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async getServerConfig (./node_modules/.pnpm/@[email protected]/node_modules/@rsbuild/core/dist/index.cjs:2629:20)
    at async createDevServer (./node_modules/.pnpm/@[email protected]/node_modules/@rsbuild/core/dist/index.cjs:3097:33)
    at async Module.start (./node_modules/.pnpm/[email protected]_@[email protected]_@[email protected]_@[email protected]__@_o2736jx4xxfyk5lxieepd5obtq/node_modules/storybook-builder-rsbuild/dist/index.js:572:25)
    at async storybookDevServer (./node_modules/.pnpm/@[email protected][email protected][email protected][email protected][email protected][email protected]/node_modules/@storybook/core-server/dist/index.js:86:8402)
    at async buildOrThrow (./node_modules/.pnpm/@[email protected][email protected][email protected][email protected][email protected][email protected]/node_modules/@storybook/core-server/dist/index.js:76:1991)
    at async buildDevStandalone (./node_modules/.pnpm/@[email protected][email protected][email protected][email protected][email protected][email protected]/node_modules/@storybook/core-server/dist/index.js:165:763)
    at async withTelemetry (./node_modules/.pnpm/@[email protected][email protected][email protected][email protected][email protected][email protected]/node_modules/@storybook/core-server/dist/index.js:86:3935)
    at async dev (./node_modules/.pnpm/@[email protected]_@[email protected]_@[email protected][email protected]_react-dom@_5kyel5bv7vemys3bvbvbl2xmyu/node_modules/@storybook/cli/dist/generate.js:989:565)

Reproduction steps

Here is a Dockerfile that describes how to build a problematic image:

FROM ubuntu:latest

ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0
ENV NVM_DIR=/root/.nvm

COPY . /app

WORKDIR /app

RUN apt-get update && apt-get install -y curl && \
  curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash && \
  . ~/.bashrc && nvm install && \
  corepack enable && pnpm i && pnpm build

EXPOSE 6006
CMD [ "bash", "-c", ". /root/.nvm/nvm.sh && pnpm run -C sandboxes/react-rsbuild storybook" ]

Root causes

The following code snippet works on macOS but will throw an error on Linux:

import net from 'node:net';

net.createServer().listen(6006, undefined); // @storybook/core
net.createServer().listen(6006, 'localhost'); // rsbuild dev server

https://github.com/storybookjs/storybook/blob/8505d86feeecd13a8473fa1372cf37500519d136/code/core/src/core-server/dev-server.ts#L66-L69

Workaround

storybook dev -p 6006 -h 0.0.0.0 can make storybook core listens to 0.0.0.0 while rsbuild still listens on localhost network, so that they don't running on the same hostname

Error: [html-rspack-plugin]: Child compilation failed

Getting the error below since the update.

image
file:rsbuild.config.ts
import { defineConfig } from "@rsbuild/core";
import { pluginReact } from "@rsbuild/plugin-react";
import { pluginSass } from "@rsbuild/plugin-sass";
import { pluginLightningcss } from "@rsbuild/plugin-lightningcss";

export default defineConfig({
	plugins: [pluginReact(), pluginSass(), pluginLightningcss()],
	source: {
		alias: {
			"@tokens": "./src/tokens",
		},
	},
});
file:./storybook/main.ts
import type { StorybookConfig } from "storybook-react-rsbuild";

const config: StorybookConfig = {
	stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
	addons: [
		"@storybook/addon-onboarding",
		"@storybook/addon-links",
		"@storybook/addon-essentials",
		"@chromatic-com/storybook",
		"@storybook/addon-interactions",
		"@storybook/addon-a11y",
	],
	framework: {
		name: "storybook-react-rsbuild",
		options: {},
	},
	docs: {},
	typescript: {
		reactDocgen: "react-docgen",
		check: true,
	},
};

export default config;

error log
storybook v8.2.4

info => Starting manager..
WARN No story files found for the specified pattern: src/**/*.mdx
info => Starting preview..
info Addon-docs: using MDX3
start   Compiling...
info Using tsconfig paths for react-docgen
error   Compile error: 
Failed to compile, check the errors for troubleshooting.
× Error: [html-rspack-plugin]: Child compilation failed:
  │   × Module build failed:
  │   ├─▶   ×   × Expression expected
  │   │     │    ╭─[data:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;:1:1]
  │   │     │  1 │ __webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;ddata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;adata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;tdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;adata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;:data:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;tdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;edata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;xdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;tdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;/data:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;jdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;adata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;vdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;adata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;sdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;cdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;rdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;idata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;pdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;tdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;,data:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;_data:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;_data:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;wdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;edata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;bdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;pdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;adata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;cdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;kdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;_data:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;pdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;udata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;bdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;ldata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;idata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;cdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;_data:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;pdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;adata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;tdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;hdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;_data:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;_data:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath; data:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;=data:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath; data:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;_data:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;_data:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;wdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;edata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;bdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;pdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;adata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;cdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;kdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;_data:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;bdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;adata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;sdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;edata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;_data:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;udata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;rdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;idata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;_data:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;_data:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath; data:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;=data:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath; data:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;hdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;tdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;mdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;ldata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;Wdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;edata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;bdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;pdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;adata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;cdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;kdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;Pdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;ldata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;udata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;gdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;idata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;ndata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;Pdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;udata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;bdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;ldata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;idata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;cdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;Pdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;adata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;tdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;hdata:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;;data:text/javascript,__webpack_public_path__ = __webpack_base_uri__ = htmlWebpackPluginPublicPath;
  │   │     │    ·                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          ─
  │   │     │    ╰────
  │   │     │
  │   │
  │   ╰─▶ Syntax Error
  │ 
  │     at /Users/ben/Projects/margin-ds/node_modules/.pnpm/@[email protected]/node_modules/@rsbuild/core/compiled/html-rspack-plugin/index.js:435:24
  │     at finalCallback (/Users/ben/Projects/margin-ds/node_modules/.pnpm/@[email protected]_@[email protected]/node_modules/@rspack/core/dist/Compiler.js:348:17)
  │     at /Users/ben/Projects/margin-ds/node_modules/.pnpm/@[email protected]_@[email protected]/node_modules/@rspack/core/dist/Compiler.js:375:20
  │     at /Users/ben/Projects/margin-ds/node_modules/.pnpm/@[email protected]_@[email protected]/node_modules/@rspack/core/dist/Compiler.js:470:28
  │     at done (/Users/ben/Projects/margin-ds/node_modules/.pnpm/@[email protected]/node_modules/@rspack/lite-tapable/dist/index.js:478:13)
  │     at AsyncSeriesHook.callAsyncStageRange (/Users/ben/Projects/margin-ds/node_modules/.pnpm/@[email protected]/node_modules/@rspack/lite-tapable/dist/index.js:485:20)
  │     at AsyncSeriesHook.callAsync (/Users/ben/Projects/margin-ds/node_modules/.pnpm/@[email protected]/node_modules/@rspack/lite-tapable/dist/index.js:88:21)
  │     at /Users/ben/Projects/margin-ds/node_modules/.pnpm/@[email protected]_@[email protected]/node_modules/@rspack/core/dist/Compiler.js:466:41
  │     at /Users/ben/Projects/margin-ds/node_modules/.pnpm/@[email protected]_@[email protected]/node_modules/@rspack/core/dist/Compiler.js:533:23

╭─────────────────────────────────────────────────────────╮
│                                                         │
│   Storybook 8.2.4 for storybook-react-rsbuild started   │
│   123 ms for manager and 1.02 s for preview             │
│                                                         │
│    Local:            http://localhost:6006/             │
│    On your network:  http://192.168.1.103:6006/         │
│                                                         │
╰─────────────────────────────────────────────────────────╯

Error: Port is occupied when starting from container

I tried to migrate the example to our workspace. It is a vscode editor + docker container. Then I found when executing storybook in the container, the port would be occupied before rsbuild dev server is created.

I haven't created something reproducible yet, so it might not be an issue with container environment.

Current observation:
By adding breakpoints, here

await readTemplate(
require.resolve(
'storybook-builder-rsbuild/templates/virtualModuleModernEntry.js.handlebars',
),
),

When readTemplate get executed, a browser window pops up. That's where two environment diverges. If I run storybook natively in the laptop, there is no port occupation. If I execute it in the container, after it executes, the port gets occupied, so rsbuild dev server would stop.

I'll continue investigating it. Do you have any idea what storybook does here and what is its possible cause?

Cannot find module error with `stories: ['../**/*.stories.ts']`

How to reproduce

In sandboxes/react-18/.storybook/main.ts, change the following:

- stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
+ stories: ['../src/**/*.mdx', '../**/*.stories.@(js|jsx|mjs|ts|tsx)'],

I tried playing around, and here are some variations

# Normal setup
['../src/**/*.stories.ts']        # Works
['../**/*.stories.ts']            # Does not work
# With more than one folder
['../src/**/*.stories.ts', '../components/**/*.stories.ts'] # Works

I double checked (just mental sanity check) that the glob is correct:

❯ glob '../**/*.stories.ts'
../src/stories/ReExportButton.stories.ts
../src/stories/Page.stories.ts
../src/stories/Header.stories.ts
../src/stories/Button.stories.ts

It works with @storybook/react-vite and @storybook/react-webpack5

Version used

Tested with the current main (commit 63c89bc4f0fff2a45ba75c2161291f9c6f78b46e) and released version 0.10.0 of storybook-builder-rsbuild.

I'm using pnpm if that makes a difference too

Support for .md / .mdx files in storybook

I am migrating my project from webpack to rsbuild and am currently in the process of trying to make storybook work with the adapted setup. Using this library, I'd have expected it to support .mdx files out of the box, as it's pretty standard for storybook.
So I started out with a simple configuration without any custom .md(x) configuration. Doesn't complain about .mdx, but about my .md import within an .mdx file. Since in webpack I have been dealing with .md files by adding a rule to treat .md as type asset/source, I thought I could simply do that here too, but to no avail. I've also used this rule successfully with rsbuild when referencing .md from within .ts files.

const storybookConfig = {
  stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
  addons: [
    '@storybook/addon-links',
    '@storybook/addon-essentials',
    '@storybook/addon-a11y',
    '@storybook/addon-designs',
  ],
  core: {
    disableTelemetry: true,
  },
  docs: {
    autodocs: true,
  },
  framework: 'storybook-react-rsbuild',
  rsbuildFinal: (config) => {
    return mergeRsbuildConfig(config, {
      tools: {
        rspack(config, { addRules }) {
          addRules([
            {
              test: /\.md$/,
              type: 'asset/source',
            },
          ]);
        },
      },
      plugins: [pluginReact()],
    });
  },
}

My suspicion is, that this rule is not applied within for .mdx files and therefore it still doesn't know what to do with that .md import in my .mdx file.
Did I simply miss some additinoal config, or is this not yet supported?
I also did try using the pluginMdx(), but that only made things worse (weird errors on .mdx files that weren't complaining without the plugin.

Unable to get storybook to build with storybook-rsbuild.

Hi,

Since adding storybook-rsbuild, I've found that I'm unable to get a build to complete.

The process always gets stuck on:

● Client ━━━━━━━━━━━━━━━━━━━━━━━━━ (70%) sealing chunk optimization

If I run it in dev mode, the iframe.html never loads - and sits in pending.

The UI shows:

start   Compiling...

The full output, for build:

$ yarn run build:storybook
@storybook/cli v7.6.19

info => Cleaning outputDir: /.storybook/dist
info => Loading presets
info => Building manager..
info => Manager built (582 ms)
info => Building preview..
info Addon-docs: using MDX3
info => Copying static files: /Users/ed.hartwellgoose/my-company/node_modules/@storybook/manager/static at /Users/ed.hartwellgoose/my-company/frontend/.storybook/dist/sb-common-assets
warn    Rsbuild plugin "rsbuild:less" registered multiple times.
● Client ━━━━━━━━━━━━━━━━━━━━━━━━━ (70%) sealing chunk optimization

For dev:

$ yarn run storybook
Initializing the Mock Service Worker at "/Users/ed.hartwellgoose/my-company/frontend/.storybook/dist"...

Service Worker successfully created!
/Users/ed.hartwellgoose/my-company/frontend/.storybook/dist/mockServiceWorker.js

Continue by creating a mocking definition module in your application:

https://mswjs.io/docs/getting-started/mocks

@storybook/cli v7.6.19

info => Serving static files from ././.storybook/dist at /
info => Starting manager..
info => Starting preview..
info Addon-docs: using MDX3
warn    Rsbuild plugin "rsbuild:less" registered multiple times.
╭─────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│                                                                                                         │
│   Storybook 7.6.19 for /Users/ed.hartwellgoose/my-company/node_modules/storybook-react-rsbuild started   │
│   1.18 s for manager and 1.61 s for preview                                                             │
│                                                                                                         │
│    Local:            https://localhost:8082/                                                            │
│    On your network:  https://my-company.dev:8082/                                                        │
│                                                                                                         │
│   A new version (8.1.6) is available!                                                                   │
│                                                                                                         │
│   Upgrade now: npx storybook@latest upgrade                                                             │
│                                                                                                         │
│   Read full changelog: https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md                  │
│                                                                                                         │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯
start   Compiling...

The terminal looks like it's running esbuild when it gets stuck.

I've tried running with various debug options, e.g. --debug or --loglevel silly, but it provides nothing new which puzzles me.

Any clues or points as to what might be the issue? Or what information would help with debugging?

Thanks,
Ed

compatibility with storybook-addon-manual-mocks

We are migrating from vite, and we are blocked by an incompatibility with https://github.com/gebeto/storybook-addon-manual-mocks
which was working perfectly with vite.

You can see the issue we ran into here : gebeto/storybook-addon-manual-mocks#19

There's also a version of this preset for webpack so we tried to use webpack addon but the error was the same.

Finally we tried to mimic the code of the addon here : https://github.com/gebeto/storybook-addon-manual-mocks/blob/main/webpack/preset.js
by overriding the rsbuild config in storybook/main.ts like that :

import { StorybookConfig } from 'storybook-react-rsbuild'
import { mergeRsbuildConfig, rspack } from '@rsbuild/core'
import path from 'path'
import fs from 'fs'

const EXTENSIONS = [".ts", ".js"]
const MOCKS_DIRECTORY = "mocks"

const config: StorybookConfig = {
  stories: [
    "../src/**/*.stories.@(ts|tsx)"
  ],
  addons: [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/addon-onboarding",
    "@storybook/addon-interactions",
    'storybook-addon-remix-react-router',
  ],
  framework: {
    name: 'storybook-react-rsbuild',
    options: {}
  },
  rsbuildFinal: (config) => {
    return mergeRsbuildConfig(config, {
      dev: {
        client: {
          overlay: false
        }
      },
      tools: {
        rspack: (config) => {
          const mocksReplacementPlugins = [
            new rspack.NormalModuleReplacementPlugin(/^\.\//, async (resource) => {
              const mockedPath = path.resolve(
                resource.context,
                MOCKS_DIRECTORY,
                resource.request
              )
              for (let ext of EXTENSIONS) {
                const isReplacementPathExists = fs.existsSync(mockedPath + ext)
                if (isReplacementPathExists) {
                  const newImportPath =
                    "./" + path.join(MOCKS_DIRECTORY, resource.request)
                  resource.request = newImportPath
                  break
                }
              }
            }),
            new rspack.NormalModuleReplacementPlugin(/^\.\.\//, async (resource) => {
              const mockedPath = path.resolve(
                resource.context,
                MOCKS_DIRECTORY,
                resource.request
              )
              for (let ext of EXTENSIONS) {
                const isReplacementPathExists = fs.existsSync(mockedPath + ext)
                if (isReplacementPathExists) {
                  const newImportPath =
                    "./" + path.join(MOCKS_DIRECTORY, resource.request)
                  resource.request = newImportPath
                  break
                }
              }
            })
          ]
          config.plugins = (config.plugins ?? []).concat(mocksReplacementPlugins)
          return config
        }
      },
      source: {
        include: [
          /node_modules[\\/]storybook-addon-remix-react-router[\\/]dist[\\/]index.js/
        ]
      }
    })
  },
  staticDirs: ['../public'],
  docs: {
    defaultName: "Docs",
    docsMode: false,
    autodocs: false,
  },
}

but still no luck : same error.

Looks like the NormalReplacement plugin has no effect, though the code is the exact copy of the webpack addon.
I really don't understand where the problem is.

Thx by advance for any kind of help.

CSS imported assets are bundled twice

When importing assets in CSS, it gets bundled twice (once by Storybook and once by rsbuild) resulting in broken URLs.

Example repo: https://github.com/Atmos4/rsbuild-storybook-demo/tree/wrong-asset-import
Branch: wrong-asset-import

Example CSS:

.asset-in-css::after {
  content: url("./assets/context.png");
  width: 10px;
  height: 10px;
}

Resulting in the following URL: /static/css/async/static/image/static/media/src/stories/assets/context.png.
The correct URL (that resolves to something) is: /static/image/static/media/src/stories/assets/context.png

Expected behavior:

Storybook should ignore those assets. Maybe there is a configuration option I can tweak to make storybook ignore these CSS assets, I am not sure.

Support for React <18

Right now, there is a problem when trying to use a version that is lower than 18.

Failed to compile, check the errors for troubleshooting.
File: javascript/esm|C:\Users\Atmos4\Workspace\rsbuild-react-storybook\node_modules\@storybook\react-dom-shim\dist\react-18.mjs:1:1
  × Resolve error: Can't resolve 'react-dom/client' in 'C:\Users\Atmos4\Workspace\rsbuild-react-storybook\node_modules\@storybook\react-dom-shim\dist'
   ╭─[1:1]
 1 │ import React, { useRef, useLayoutEffect } from 'react';
 2 │ import ReactDOM from 'react-dom/client';
   ·                      ──────────────────
 3 │
 4 │ var nodes=new Map,WithCallback=({callback,children})=>{let once=useRef();return useLayoutEffect(()=>{once.current!==callback&&(once.current=callback,callback());},[callback]),children},renderElement=async(node,el,rootOptions)=>{let root=await getReactRoot(el,rootOptions);return new Promise(resolve=>{root.render(React.createElement(WithCallback,{callback:()=>resolve(null)},node));})},unmountElement=(el,shouldUseNewRootApi)=>{let root=nodes.get(el);root&&(root.unmount(),nodes.delete(el));},getReactRoot=async(el,rootOptions)=>{let root=nodes.get(el);return root||(root=ReactDOM.createRoot(el,rootOptions),nodes.set(el,root)),root};

I believe that if used correctly, @storybook/react-dom-shim will target the correct React DOM import (react-dom instead of react-dom/client).

Reproduction

From the /sandboxes/react-rsbuild, change the React version to 16 or 17.

Asset loading in CSS doesn't work in dev

Note: this is just me reopening #66 with more details

Problem

When trying to load assets in CSS with a default storybook configuration, it doesn't work in dev and will not load the asset properly.

Example repo: https://github.com/Atmos4/rsbuild-storybook-demo/tree/css-asset-loading-not-working
branch css-asset-loading-not-working

Example code:

.asset-in-css::after {
  content: url("./assets/context.png"); /* <-- this asset will not load in dev */
  width: 10px;
  height: 10px;
}

Temporary solution

Add this to .storybook/main.ts

export default {
  ... your config
  rsbuildFinal: (config) => {
    config.output ||= {};
    config.output.distPath = {
      image: ".",
      font: ".",
      svg: ".",
    };
    return config;
  },
} satisfies StorybookConfig;

Support for storybook / rsbuild / module federation setup

Hello there

I've got a project that makes use of module federation (just migrated from webpack to rsbuild) but now I can't get storybook to properly start up with my module federation dependency configured.
Here's the relevant part of my storybook / rsbuild config:

{
...
framework: 'storybook-react-rsbuild',
  rsbuildFinal: (config) => {
    return mergeRsbuildConfig(config, {
      plugins: [pluginReact()],
      moduleFederation: {
        options: {
          name: '_my_library',
          filename: '_my_library.js',
          remotes: {
            _my_remote: '_my_remote@http://localhost:3050/_my_remote.js',
          },
          shared: {
            react: { singleton: true },
            'react-dom': { singleton: true },
          },
        },
      },
    });
  },
}

I don't think this library supports this usecase yet, as I'm getting errors after starting up the app.

The loadShareSync function was unable to load react. The react could not be found in _my_library.
        Possible reasons for failure: 

        1. The react share was registered with the 'get' attribute, but loadShare was not used beforehand.

        2. The react share was not registered with the 'lib' attribute.

When using webpack, I've managed to get module federation imports working by using storybook-module-federation. I suspect that this doesn't work yet because of the missing initial dynamic import. That seems to have been the issue with this similar issue here
So if I'm doing something wrong in using module federation together with storybook / rsbuild, please provide a working example or some guidance here. If it's not yet supported at all, please consider implementing it soon ❤️

Support Nx

Hi, I'm getting a strange error. How can I enable cache?

$ yarn nx run ui:export-storybook --skip-nx-cache --verbose
yarn run v1.22.18
$ cross-env NODE_OPTIONS=--max-old-space-size=16000 nx run ui:export-storybook --skip-nx-cache --verbose

> nx run ui:export-storybook

^[[44;1R

 NX  Storybook builder starting ...

info => Cleaning outputDir: \dist\storybook\ui
info => Loading presets
info => Building manager..
info => Manager built (334 ms)
info => Building preview..
info Addon-docs: using MDX3
info => Copying static files: c:\monorepo\node_modules\@storybook\manager\static at c:\monorepo\dist\storybook\ui\sb-common-assets
=> Failed to build the preview

 NX   Cache is required


Error: Cache is required
    at iframe_rsbuild_config_default (c:\monorepo\node_modules\storybook-builder-rsbuild\dist\index.js:363:11)
    at async rsbuild (c:\monorepo\node_modules\storybook-builder-rsbuild\dist\index.js:523:25)
    at async Module.build (c:\monorepo\node_modules\storybook-builder-rsbuild\dist\index.js:605:18)
    at async Promise.all (index 0)
    at async buildStaticStandalone (c:\monorepo\node_modules\@storybook\core-server\dist\index.js:61:2295)
    at async buildStorybookExecutor (c:\monorepo\node_modules\@nx\storybook\src\executors\build-storybook\build-storybook.impl.js:14:5)
    at async promiseToIterator (c:\monorepo\NODE_M~1\nx\src\command-line\run\run.js:32:11)
    at async getLastValueFromAsyncIterableIterator (c:\monorepo\NODE_M~1\nx\src\utils\async-iterator.js:13:19)
    at async iteratorToProcessStatusCode (c:\monorepo\NODE_M~1\nx\src\command-line\run\run.js:43:29)
    at async handleErrors (c:\monorepo\NODE_M~1\nx\src\utils\params.js:9:16)

——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

 NX   Running target export-storybook for project ui failed

Failed tasks:

- ui:export-storybook


Unable to resolve package with source build plugin in a monorepo

Reproduction

https://github.com/yf-yang/rsbuild-storybook-monorepo

Steps

cd packages/pkg1
pnpm i
pnpm storybook

Details

@rsbuild/plugin-source-build is used in a monorepo. However, the dependency package pkg2 could not be correctly resolved. I've hooked source build plugin code. If I got it right, the packages/tsconfig references are correctly configured.

Did I miss something and configure something wrong, or is this a bug?

Additional information

https://github.com/yf-yang/rsbuild-storybook-monorepo/blob/main/patches/%40rsbuild__plugin-source-build%400.7.9.patch#L9-L10

This is another bug (rule.resolve.conditionNames is not initialized, so it is actually undefined).

react-docgen-typescript support?

Trying to auto generate controls for stories. I have used react-docgen-typescript on other Storybook builds but was getting error mentioning it isn't supported.

=> Failed to build the preview
Error: Rspack didn't support the hooks `react-docgen-typescript`' required

Adding my main.tsx file below

.storybook/main.ts
import type { StorybookConfig } from "storybook-react-rsbuild";

const config: StorybookConfig = {
	stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
	addons: [
		"@storybook/addon-onboarding",
		"@storybook/addon-links",
		"@storybook/addon-essentials",
		"@chromatic-com/storybook",
		"@storybook/addon-interactions",
		"@storybook/addon-a11y",
	],
	framework: {
		name: "storybook-react-rsbuild",
		options: {},
	},
	docs: {},
	typescript: {
		reactDocgen: "react-docgen-typescript",
		reactDocgenTypescriptOptions: {
			shouldExtractLiteralValuesFromEnum: true,
			propFilter: (prop) =>
				prop.parent ? !/node_modules/.test(prop.parent.fileName) : true,
		},
		check: true,
	},
};

export default config;

Parsing non TS/JS files giving error

I encountered an issue while working with the project where non-JavaScript or TypeScript files are being parsed, leading to errors.
Here are the details:

File: C:\Users\Admin\Desktop\WorkingFiles\react-rsbuild\src\tools\generate-components-output-file\windws.ps1:1:1

  × Module parse failed:
  ╰─▶   × JavaScript parsing error: Expected ';', '}' or <eof>
         ╭─[1:1]
       1 │ $rootPath = "test_root_path" # Set your components root folder path here
         ·                              ─
       2 │ $outputFile = "test_root_path" # Set your output file path here
         ╰────
  help:
        You may need an appropriate loader to handle this file type.

It tries to parse all files, including PDFs, text files, and PS1 scripts, within the src folder. I also tried to exclude the tools folder, but it still attempts to parse these files.

image

I'm not even using these files in the code but they still get pick up and being process

error binding.JsResolverFactory is not a constructor

I try to migrate from storybook/vite to storybook with rsbuild but I run into a build error :

excerp of package.json :

"@rsbuild/core": "1.0.1-beta.0",
    "@rsbuild/plugin-eslint": "1.0.0",
    "@rsbuild/plugin-react": "1.0.1-beta.0",
    "@rsbuild/plugin-type-check": "1.0.1-beta.0",
    "@rsdoctor/rspack-plugin": "^0.3.7",
    "@storybook/addon-essentials": "8.2.2",
    "@storybook/addon-interactions": "8.2.2",
    "@storybook/addon-links": "8.2.2",
    "@storybook/addon-onboarding": "8.2.2",
    "@storybook/blocks": "8.2.2",
    "@storybook/react": "8.2.2",
    "@storybook/react-vite": "8.2.2",
    "@storybook/test": "8.2.2",
    "@storybook/test-runner": "0.19.0",
    "msw-storybook-addon": "2.0.3",
    "playwright": "1.45.1",
    "react-test-renderer": "18.3.1",
    "storybook": "8.2.2",
    "storybook-addon-manual-mocks": "1.0.4",
    "storybook-react-rsbuild": "0.0.7",
    "storybook-addon-remix-react-router": "3.0.0",

storybook/main.ts

import { StorybookConfig } from 'storybook-react-rsbuild'

const config: StorybookConfig = {
  stories: [
    "../src/**/*.stories.@(ts|tsx)"
  ],
  addons: [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/addon-onboarding",
    "@storybook/addon-interactions",
    {
      name: "storybook-addon-manual-mocks/vite",
      options: {
        mocksFolder: "mocks",
      }
    },
    'storybook-addon-remix-react-router',
  ],
  framework: {
    name: 'storybook-react-rsbuild',
    options: {}
  },
  rsbuildFinal: (config) => {
    // see https://github.com/rspack-contrib/storybook-rsbuild#customize-the-rsbuild-config
    // Customize the final Rsbuild config here
    return config;
  },
  staticDirs: ['../public'],
  docs: {
    defaultName: "Docs",
    docsMode: false,
    autodocs: false,
  },
}

export default config

rsbuild config :

import { defineConfig } from '@rsbuild/core'
import { pluginReact } from '@rsbuild/plugin-react'
import { RsdoctorRspackPlugin } from '@rsdoctor/rspack-plugin'
import { pluginTypeCheck } from '@rsbuild/plugin-type-check'
import { pluginEslint } from '@rsbuild/plugin-eslint'

const shouldUseRsdoctor = process.env.RSDOCTOR === 'true'

export default defineConfig({
  server: {
    port: 3001,
  },
  html: {
    title: "Application paie",
  },
  source: {
    entry: {
      index: './src/index.tsx',
    }
  },
  output: {
    distPath: {
      root: 'build'
    },
    cleanDistPath: true
  },
  plugins: [
    /** désactivé car prend trop de mémoire, souvent OOM */
    pluginTypeCheck({ enable: false }),
    /** désactivé car prend presque 30s lors du build */
    pluginEslint({ enable: false }),
    pluginReact()
  ],
  tools: {
    rspack(config, { appendPlugins }) {
      // Only register the plugin when RSDOCTOR is true, as the plugin will increase the build time.
      if (shouldUseRsdoctor) {
        appendPlugins(
          new RsdoctorRspackPlugin({
            // voir https://rsdoctor.dev/guide/usage/rule-config pour la configuration des règles
            linter: {
              //  When set to `'Error'`, all rules will be executed
              level: 'Error',
              extends: [],
              rules: {
                'default-import-check': 'on',
                'duplicate-package': 'on',
                'loader-performance-optimization': 'on',
                // par défaut, c'est ES5, ce qui est trop bas pour notre app
                // et on ne peut changer que pour ES6 (trop bas aussi) ou ES7+ (tout ce qui ES7 ou plus) donc aucun intéret à garder la règle
                'ecma-version-check': "off",
              },
            },
          })
        )
      }
      config.experiments = {
        ...(config.experiments ?? {}),
        // https://www.rspack.dev/config/experiments#experimentslazycompilation
        // désactivé car ne semble pas fonctionner correctement
        lazyCompilation: false
      }
      return config
    }
  }
})

with this command
cross-env NODE_OPTIONS=--max-old-space-size=8192 storybook dev -p 6006
I get the following error :

info => Serving static files from ./.\public at /
info => Starting manager..
info => Starting preview..
info Addon-docs: using MDX3
=> Failed to build the preview
TypeError: binding.JsResolverFactory is not a constructor
    at new ResolverFactory (.\node_modules\@rspack\core\dist\ResolverFactory.js:47:64)
    at new Compiler (.\node_modules\@rspack\core\dist\Compiler.js:148:32)
    at createCompiler (.\node_modules\@rspack\core\dist\rspack.js:44:22)
    at create (.\node_modules\@rspack\core\dist\rspack.js:89:26)
    at rspack (.\node_modules\@rspack\core\dist\rspack.js:115:37)
    at createCompiler (.\node_modules\@rsbuild\core\dist\index.cjs:2698:73)
    at async createDevMiddleware (.\node_modules\@rsbuild\core\dist\index.cjs:2771:16)
    at async startCompile (.\node_modules\@rsbuild\core\dist\index.cjs:4261:41)
    at async createDevServer (.\node_modules\@rsbuild\core\dist\index.cjs:4306:45)
    at async Module.start (.\node_modules\storybook-builder-rsbuild\dist\index.js:622:25)

WARN Broken build, fix the error above.

Broken with [email protected]

Reproduction link: https://github.com/yf-yang/rsbuild-storybook-esm/tree/sb8.2

pnpm storybook
Error: Cannot find module '@storybook/preview/globals'
Require stack:
- ./node_modules/.pnpm/[email protected]_@[email protected]_@[email protected]_@swc+helpers@0_pealok2q6itvioioojy46f42v4/node_modules/storybook-builder-rsbuild/dist/index.js
    at Module._resolveFilename (node:internal/modules/cjs/loader:1048:15)
    at Module._resolveFilename (./node_modules/.pnpm/[email protected][email protected]/node_modules/esbuild-register/dist/node.js:4799:36)
    at Module._load (node:internal/modules/cjs/loader:901:27)
    at Module.require (node:internal/modules/cjs/loader:1115:19)
    at require (node:internal/modules/helpers:130:18)
    at Object.<anonymous> (./node_modules/.pnpm/[email protected]_@[email protected]_@[email protected]_@swc+helpers@0_pealok2q6itvioioojy46f42v4/node_modules/storybook-builder-rsbuild/dist/index.js:132:22)
    at Module._compile (node:internal/modules/cjs/loader:1241:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1295:10)
    at Object.newLoader (./node_modules/.pnpm/[email protected][email protected]/node_modules/esbuild-register/dist/node.js:2262:9)
    at extensions..js (./node_modules/.pnpm/[email protected][email protected]/node_modules/esbuild-register/dist/node.js:4838:24)

storybook-react-rsbuild does not limit storybook versions, so cannot downgrade storybook-react-rsbuild's dependency version now.

Compilation error "JavaScript parsing error: Expected ';', got 'assert'"

I try to migrate from storybook/vite to storybook with rsbuild but I have a compilation error :

cross-env NODE_OPTIONS=--max-old-space-size=8192 storybook dev -p 6006

info => Serving static files from ./.\public at /
info => Starting manager..
info => Starting preview..
info Addon-docs: using MDX3
start   Compiling...
info Using tsconfig paths for react-docgen
error   Compile error: 
Failed to compile, check the errors for troubleshooting.
× Conflict: Multiple assets emit different content to the same filename iframe.html

  × JavaScript parsing error: Expected ';', got 'assert'
         ╭─[1:1]
       1 │ import { makeDecorator, addons } from '@storybook/preview-api';
       2 │ import P, { useState, useMemo, useCallback, useRef } from 'react';
       3 │ import de from '../package.json' assert { type: 'json' };
         ·                                  ──────
       4 │ import { createMemoryRouter, RouterProvider, UNSAFE_RouteContext, useLocation, useParams, useSearchParams, useNavigationType } from 'react-router-dom';
       5 │
         ╰────
      
  help: 
        You may need an appropriate loader to handle this file type.

excerp of package.json :

"@rsbuild/core": "1.0.1-beta.1",
    "@rsbuild/plugin-eslint": "1.0.0",
    "@rsbuild/plugin-react": "1.0.1-beta.1",
    "@rsbuild/plugin-type-check": "1.0.1-beta.1",
    "@rsdoctor/rspack-plugin": "^0.3.7",
    "@storybook/addon-essentials": "8.2.2",
    "@storybook/addon-interactions": "8.2.2",
    "@storybook/addon-links": "8.2.2",
    "@storybook/addon-onboarding": "8.2.2",
    "@storybook/blocks": "8.2.2",
    "@storybook/react": "8.2.2",
    "@storybook/react-vite": "8.2.2",
    "@storybook/test": "8.2.2",
    "@storybook/test-runner": "0.19.0",
    "msw-storybook-addon": "2.0.3",
    "playwright": "1.45.1",
    "react-test-renderer": "18.3.1",
    "storybook": "8.2.2",
    "storybook-addon-manual-mocks": "1.0.4",
    "storybook-react-rsbuild": "0.0.7",
    "storybook-addon-remix-react-router": "3.0.0",
    "resolutions": {
       "@storybook/csf": "0.1.11"
    },

storybook/main.ts

import { StorybookConfig } from 'storybook-react-rsbuild'

const config: StorybookConfig = {
  stories: [
    "../src/**/*.stories.@(ts|tsx)"
  ],
  addons: [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/addon-onboarding",
    "@storybook/addon-interactions",
    {
      name: "storybook-addon-manual-mocks/vite",
      options: {
        mocksFolder: "mocks",
      }
    },
    'storybook-addon-remix-react-router',
  ],
  framework: {
    name: 'storybook-react-rsbuild',
    options: {}
  },
  rsbuildFinal: (config) => {
    // see https://github.com/rspack-contrib/storybook-rsbuild#customize-the-rsbuild-config
    // Customize the final Rsbuild config here
    return config;
  },
  staticDirs: ['../public'],
  docs: {
    defaultName: "Docs",
    docsMode: false,
    autodocs: false,
  },
}

export default config

rsbuild config :

import { defineConfig } from '@rsbuild/core'
import { pluginReact } from '@rsbuild/plugin-react'
import { RsdoctorRspackPlugin } from '@rsdoctor/rspack-plugin'
import { pluginTypeCheck } from '@rsbuild/plugin-type-check'
import { pluginEslint } from '@rsbuild/plugin-eslint'

const shouldUseRsdoctor = process.env.RSDOCTOR === 'true'

export default defineConfig({
  server: {
    port: 3001,
  },
  html: {
    title: "Application paie",
  },
  source: {
    entry: {
      index: './src/index.tsx',
    }
  },
  output: {
    distPath: {
      root: 'build'
    },
    cleanDistPath: true
  },
  plugins: [
    /** désactivé car prend trop de mémoire, souvent OOM */
    pluginTypeCheck({ enable: false }),
    /** désactivé car prend presque 30s lors du build */
    pluginEslint({ enable: false }),
    pluginReact()
  ],
  tools: {
    rspack(config, { appendPlugins }) {
      // Only register the plugin when RSDOCTOR is true, as the plugin will increase the build time.
      if (shouldUseRsdoctor) {
        appendPlugins(
          new RsdoctorRspackPlugin({
            // voir https://rsdoctor.dev/guide/usage/rule-config pour la configuration des règles
            linter: {
              //  When set to `'Error'`, all rules will be executed
              level: 'Error',
              extends: [],
              rules: {
                'default-import-check': 'on',
                'duplicate-package': 'on',
                'loader-performance-optimization': 'on',
                // par défaut, c'est ES5, ce qui est trop bas pour notre app
                // et on ne peut changer que pour ES6 (trop bas aussi) ou ES7+ (tout ce qui ES7 ou plus) donc aucun intéret à garder la règle
                'ecma-version-check': "off",
              },
            },
          })
        )
      }
      config.experiments = {
        ...(config.experiments ?? {}),
        // https://www.rspack.dev/config/experiments#experimentslazycompilation
        // désactivé car ne semble pas fonctionner correctement
        lazyCompilation: false
      }
      return config
    }
  }
})

`Conflict: Multiple assets emit different content to the same filename iframe.html` when using custom `source.entry`

Firstly, thank you for making this! I have been migrating from Vite to Rsbuild because of numerous issues with Vite and it has been smooth sailing for the most part. 🙌

Problem

In my rsbuild.config.ts, I have the following:

tools: {
  htmlPlugin: false,
},
source: {
  entry: {
    index: './src/client/main.tsx',
  },
},

This is because I don't use the index.html provided by Rsbuild and instead render the script tags in my backend.

However, this results in Conflict: Multiple assets emit different content to the same filename iframe.html when running Storybook.

Workaround

Adding the following to the Storybook config make the error go away:

rsbuildFinal(config) {
  delete config.source.entry.index
  return config
},

Built SB has odd selectors that is being applied

Hey team, I noticed some discrepancies between the dev mode vs built files.

For example, & li+li appears on a built files which has higher priorities than the css I have for my components. (I am using CSS at-layers rule for my components)

Screenshot of built

image
image

Build

https://tounsoo.github.io/margin-ds/?path=/story/component-listbox--default

SB team response

On further inspection it looks like it might be an issue with storybook-rsbuild. At least if you check out the build output from React+Vite and React+Webpack examples, you'll see the <style> tag will contain this:
image
but in your example it's minified+compiled, which produces the wrong selector.
It could also be a webpack-plugin in your setup that compiles the styles wrong, not supporting the CSS nesting syntax with &.
If you could create a minimal reproduction and open a bug report that would be great 👍

Support for --webpack-stats-json

Hey everyone! First of all, thanks for this nice plugin!

I was wondering if I would still be able to output a stats file by using it, as I currently do with Webpack, by running storybook build --webpack-stats-json.
Is that supported?

How to use rspack.config.js configuration?

Since rspack is designed with compatibility with webpack in mind, migrating from webpack to rspack seems natural. However, in Storybook, the config is read using webpack, whereas for Storybook compatibility with rspack, rsbuild is used instead. Therefore, it seems necessary to convert rspack config further to rsbuild. Is it possible to use rspack configuration directly with storybook-rsbuild?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.