Alex Karpov
Alex Karpov

Reputation: 329

Storybook Canvas: 'ReferenceError: react is not defined'

Newbie to Storybook here.

I'm trying to integrate Storybook into my Gatsby front end. However, when trying to preview the test components in Storybook Canvas I get the following error:

react is not defined ReferenceError: react is not defined at react-dom/client (http://localhost:6006/main.iframe.bundle.js:1970:18) at webpack_require (http://localhost:6006/runtime~main.iframe.bundle.js:28:33) at fn (http://localhost:6006/runtime~main.iframe.bundle.js:339:21) at webpack_require.t (http://localhost:6006/runtime~main.iframe.bundle.js:106:38)

enter image description here

I'm able to see the component preview in Storybook Docs but not in Storybook Canvas.

Link to repository: https://github.com/akarpov91/gatsby-tutorial

Upvotes: 13

Views: 13056

Answers (8)

gwizxs
gwizxs

Reputation: 1

if you use setting up webpack from scratch - npx storybook@latest add @storybook/addon-webpack5-compiler-babel or npx storybook@latest add @storybook/addon-webpack5-compiler-swc

Upvotes: -1

DisplayNun
DisplayNun

Reputation: 1

In my .babelrc.js, replaced

'@babel/preset-react',

to

['@babel/preset-react', { runtime: 'automatic' }]

Worked like a charm.

Upvotes: -1

Shura
Shura

Reputation: 667

This worked for me:

swc: () => ({
  jsc: {
    transform: {
      react: {
        runtime: 'automatic'
      }
    }
  }
}),

Upvotes: 1

Khang Dinh
Khang Dinh

Reputation: 94

I had the same problem just now. The fix for me was simply adding this to the .storybook/preview.js file:

import * as React from 'react'

For context, here's my setup:

Also: I stumbled upon this problem just by upgrading from Node.js 16 to Node.js latest (v22 at the time). For whatever wacky reason, React was implicitly loaded in scope previously when running Storybook, now it's not, so I gotta explicitly import it - happy to hear more insights / pointers on this from anyone

PS: I add this answer only to potentially help someone else with the same issue - not guaranteeing it'll work for everyone.

Upvotes: 0

y0na24
y0na24

Reputation: 349

If you use new versions of Storybook, it uses SWC compiler by default and you need to change config a little bit. enter link description here

const config: StorybookConfig = {
  stories: ['../../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
  addons: [
    '@storybook/addon-links',
    '@storybook/addon-essentials',
    '@storybook/addon-onboarding',
    '@storybook/addon-interactions'
  ],
  framework: {
    name: '@storybook/react-webpack5',
    options: {
      builder: {
        useSWC: true
      }
    }
  },
  swc: () => ({
    jsc: {
      transform: {
        react: {
          runtime: 'automatic'
        }
      }
    }
  }),
  docs: {
    autodocs: 'tag'
  }
}

Upvotes: 34

Matt Smith
Matt Smith

Reputation: 559

For me the solution was to remove the following lines from the main.js file:

 // Use correct react-dom depending on React version.
 if (parseInt(React.version) <= 18) {
   config.externals = ['react-dom/client'];
 }

Upvotes: -1

Nikki Pantony
Nikki Pantony

Reputation: 173

I have had the same problem, try copying this into your .storybook/main.js config. Hope this works for you too.

module.exports = {
  // You will want to change this to wherever your Stories will live
  stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
  addons: ["@storybook/addon-links", "@storybook/addon-essentials"],
  framework: "@storybook/react",
  core: {
    builder: "webpack5",
  },
  webpackFinal: async config => {
    // Transpile Gatsby module because Gatsby includes un-transpiled ES6 code.
    config.module.rules[0].exclude = [/node_modules\/(?!(gatsby)\/)/]

    // Use installed babel-loader which is v8.0-beta (which is meant to work with @babel/core@7)
    config.module.rules[0].use[0].loader = require.resolve("babel-loader")

    // Use @babel/preset-react for JSX and env (instead of staged presets)
    config.module.rules[0].use[0].options.presets = [
      require.resolve("@babel/preset-react"),
      require.resolve("@babel/preset-env"),
    ]

    config.module.rules[0].use[0].options.plugins = [
      // Use @babel/plugin-proposal-class-properties for class arrow functions
      require.resolve("@babel/plugin-proposal-class-properties"),

      // Use babel-plugin-remove-graphql-queries to remove graphql queries from components when rendering in Storybook
      // While still rendering content from useStaticQuery in development mode
      [
        require.resolve("babel-plugin-remove-graphql-queries"),
        {
          stage: config.mode === `development` ? "develop-html" : "build-html",
          staticQueryDir: "page-data/sq/d",
        },
      ],
    ]

    return config
  },
}

Upvotes: 0

Ferran Buireu
Ferran Buireu

Reputation: 29335

Try adding the following snippet in your main.js:

module.exports = {
  // ...
  babel: async (options) => ({
    ...options,
    presets: [
      ...options.presets,
      [
    '@babel/preset-react', {
      runtime: 'automatic',
    },
        'preset-react-jsx-transform'
      ],
    ],
  }),
};

Apparently, @storybook/react adds @babel/preset-react without runtime: 'automatic' property

Upvotes: 4

Related Questions