📣 Storybook in Redwood is moving to Vite!

How does Storybook work today?

Today, when you run yarn redwood storybook, there are two important things to be aware of:

  • The config used lives in the @redwoodjs/testing package.
    • When Storybook was added to Redwood, Framework Packages did not yet exist. Therefore, we had to more tightly couple Storybook within the framework.
    • This is in contrast to the default place for Storybook config files, the in-project .storybook directory.
  • Storybook is built using Webpack.
    • This is simply because, as you may know, Webpack used to be the default bundler.

What is changing, and why?

Vite has been the default bundler for just over a year, and Storybook has been the primary holdout for this migration — until now!

Additionally, now that Storybook supports Framework Packages, we felt this migration was a natural time to move the Storybook config out of the monorepo and into your projects.

This means that you’ll get two primary advantages:

:rotating_light:Before you continue, please note:

  • Currently, only projects using Typescript are supported.
  • If you are still using Webpack, this is not for you, and you should consider switching to Vite :wink:

How do I upgrade?

Getting started is easy — you’ll first want to make sure you’re on the latest Redwood canary, and then run:

yarn redwood storybook-vite

On first run, we’ll create the following config files for you:

  • web/.storybook/main.ts
  • web/.storybook/preview-body.html
    • This is required to change the id of the root div to redwood-app, which is what the entry file used by Vite requires.

Then, as usual, Storybook should open in your browser!

If you don’t have any of your own Storybook configuration, you should be good to go.

If you do have custom Storybook configuration, then you’ll need to manually migrate it over to the new files. For example, if you’ve got any global decorators, you can now just follow the official Storybook docs on that: Decorators • Storybook docs

And, of course, if you run into any problems or have any questions, we’d love to hear about it.

3 Likes

I’m only getting a bunch of these:

import_react_dom.default.unmountComponentAtNode is not a function

I thought it was due to my locale setup, but even after I did that, it doesn’t seem to work.

Even if I just do yarn rw g component TestComponent that component throws with that error in storybook.

Interestingly to get GitHub - stevensacks/storybook-react-i18next: Storybook i18next addon to work, I needed to manually install @storybook/icons, is that intended?

That is super weird - thanks for letting us know, I’ll generate a component and check it out! Would you mind also providing anything more about your setup that may be helpful?

As for add ons, if you take a look at your new web/.storybook/main.ts file, you’ll see that the only add on we’re installing for you is @storybook/addon-essentials. By comparison, you can see what addons are included in the Webpack one here — the only difference is that the Webpack one optionally includes @storybook/addon-a11y.

I don’t know anything about storybook-react-i18next specifically, though generally the requirements of an add on are the purview of that add on. However, we can definitely explore having the new Storybook setup ship with more installed by default. Were you previously using that add on with the Webpack version?

EDIT: @razzeee, I’m having trouble reproducing your error:

Can you tell me a little more? Have you tried doing git clean and/or yarn cache clean?

Just tried that, didn’t help

No, we were using a custom config/storybook.preview.js:

import i18n from 'i18next'
import detector from 'i18next-browser-languagedetector'
import { initReactI18next } from 'react-i18next'

import de from '../src/i18n/de/common.json'
import en from '../src/i18n/en/common.json'

i18n
  .use(detector)
  .use(initReactI18next)
  .init({
    resources: {
      en: en,
      de: de,
    },
    fallbackLng: 'en',

    interpolation: {
      escapeValue: false,
    },
  })

But it seemed easier to use that addon.

Just was wondering, if a default storybook (non redwood) ships the icons package by default, as the readme of GitHub - stevensacks/storybook-react-i18next: Storybook i18next addon doesn’t mention it at all.

Uncaught (in promise) TypeError: import_react_dom.default.render is not a function
    renderElement react-16.mjs:3
    renderElement react-16.mjs:3
    render chunk-VT6XBPNA.js:2394
    promise callback*DocsRenderer/this.render/< chunk-VT6XBPNA.js:2394
    render chunk-VT6XBPNA.js:2393
    renderDocs runtime.js:92
    renderToElement runtime.js:92
    renderSelection runtime.js:101
    selectSpecifiedStory runtime.js:101
    initializeWithStoryIndex runtime.js:92
    _runResolutions runtime.js:4
    _runResolutions runtime.js:4
    then runtime.js:4
    initializeWithStoryIndex runtime.js:92
    initializeWithProjectAnnotations runtime.js:87
    promise callback*initializeWithProjectAnnotations runtime.js:87
    initialize runtime.js:81
    _runResolutions runtime.js:4
    _runResolutions runtime.js:4
    _setResolved runtime.js:4
    _continueWith runtime.js:4
    _runResolutions runtime.js:4
    _runResolutions runtime.js:4
    _setResolved runtime.js:4
    _continueWith runtime.js:4
    _handleUserFunctionResult runtime.js:4
    _runResolutions runtime.js:4
    _runResolutions runtime.js:4
    _setResolved runtime.js:4
    _continueWith runtime.js:4
    _chainPromiseData runtime.js:4
    promise callback*_chainPromiseData runtime.js:4
    _handleUserFunctionResult runtime.js:4
    _runResolutions runtime.js:4
    _runResolutions runtime.js:4
    then runtime.js:4
    getProjectAnnotationsOrRenderError runtime.js:81
    initialize runtime.js:81
    <anonymous> vite-app.js:25
react-16.mjs:3:65

I thought it might be caused by headlessui-float, but that didn’t turn out to be true.

It also seems to happen, if I just take our project and migrate to storybook vite without changing anything of the default addon. I can try one of our other redwood projects.

I’m out of ideas for now, I’ve taken our smallest project and migrated it, added a new TestComponent and removed everything else from the storybook (or well that solution) - even trimmed down the App.tsx to the minimum. The error is still there.

Only thing I can still think of, is comparing our tsconfig.json with the default one

Thanks for this info!

My understanding is that by default, Storybook ships only with these essential add ons: Essential addons • Storybook docs

How did you figure out that you needed to include the icons add on?

On your error call stack, the one thing that jumps out to me is — are you using React 16? I think Redwood has been using React 18 since v5…

Otherwise, if you don’t have a repo that you can share, can you please provide repro steps?

Building storybook complained, that it needs that package, so that was very obvious.

Hrm, that’s weird. The project has been around for some time, so that might fit with when it was created, but we’re not referencing that.

❯ yarn why react
├─ @redwoodjs/auth@npm:8.0.0-canary.757
│  └─ react@npm:19.0.0-beta-04b058868c-20240508 (via npm:19.0.0-beta-04b058868c-20240508)
│
├─ @redwoodjs/vite@npm:8.0.0-canary.757
│  └─ react@npm:19.0.0-beta-04b058868c-20240508 (via npm:19.0.0-beta-04b058868c-20240508)
│
└─ web@workspace:web
   └─ react@npm:19.0.0-beta-04b058868c-20240508 (via npm:19.0.0-beta-04b058868c-20240508)

Tried to delete and regenerate yarn.lock but doesn’t help with the error

1 Like

I might be able to find some time in the next days, to clean out one of our projects and hopefully share it.

1 Like

Sounds good! :slight_smile: This would definitely be helpful as I can’t reproduce it otherwise.

Figured out how to repro! Opened a bug here: [Bug?]: Upgrading Redwood to Canary causes "unmountComponentAtNode is not a function" in Storybook · Issue #10815 · redwoodjs/redwood · GitHub

1 Like