Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

It's not possible to export decorator that contains React or HTML tags Storybook 6.0 #11723

Closed
bdobry opened this issue Jul 29, 2020 · 3 comments

Comments

@bdobry
Copy link

bdobry commented Jul 29, 2020

Describe the bug
When trying to export a decorator that contains React or HTML tags, Storybook returns an error.

To Reproduce
Steps to reproduce the behavior:

  1. Create a preview.js with for example:
export const decorators = [story => <div>story()</div>];
  1. Run Storybook
  2. See error:
    You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.
    image

Expected behavior
Storybook exports decorator

Additional context
I tried adding such rule to webpack:

{
    test: /\.js?$/,
    use: "babel-loader",
    exclude: /node_modules/
}

but then the error is:
Support for the experimental syntax 'jsx' isn't currently enabled
image

My main goal here was to globally wrap my components with <MemoryRouter /> from react-router-dom and Redux <Provider /> instead of doing that every time. If there's any other way of doing that I'm open for suggestions.

Code snippets

// main.js
const appConfig = require("../webpack.config");

module.exports = {
  addons: [
    "@storybook/addon-viewport",
    {
      name: "@storybook/addon-docs",
      options: {
        configureJSX: true,
        babelOptions: {},
        sourceLoaderOptions: null
      }
    }
  ],
  stories: ["../src/**/*.stories.tsx"],
  typescript: {
    check: false,
    checkOptions: {},
    reactDocgen: "react-docgen-typescript",
    reactDocgenTypescriptOptions: {
      shouldExtractLiteralValuesFromEnum: true,
      shouldRemoveUndefinedFromOptional: true,
      propFilter: prop =>
        prop.parent ? !/node_modules/.test(prop.parent.fileName) : true
    }
  },
  webpackFinal: config => {
    return {
      ...config,
      module: {
        ...config.module,
        rules: appConfig.module.rules
      },
      resolve: {
        ...config.resolve,
        alias: appConfig.resolve.alias
      }
    };
  }
};

System:
System:
OS: macOS 10.15.4
CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz

Binaries:
Node: 12.16.3 - /usr/local/bin/node
Yarn: 1.22.4 - /usr/local/bin/yarn
npm: 6.14.5 - /usr/local/bin/npm

Browsers:
Chrome: 84.0.4147.89
Firefox: 78.0.2
Safari: 13.1

npmPackages:
@storybook/addon-docs: 6.0.x-rc.16 => 6.0.0-rc.16
@storybook/addon-viewport: 6.0.x-rc.16 => 6.0.0-rc.16
@storybook/addons: 6.0.x-rc.16 => 6.0.0-rc.16
@storybook/react: 6.0.x-rc.16 => 6.0.0-rc.16

@shilman
Copy link
Member

shilman commented Aug 3, 2020

Is this a regression, i.e. are you upgrading the project from 5.x and it was working there?

@bdobry
Copy link
Author

bdobry commented Aug 3, 2020

@shilman No, I kicked off with 6.0 rc but looking at some other threads and examples I'd expect this to work but maybe I misunderstood some documentation. I can try to reproduce this case with 5.3 later today using addDecorator() method instead of new export const decorators = [];

edit: Also, for people coming here in the future looking for some workarounds I went for splitting components into "connected" and "not connected" for Redux and react-router-dom so that:

const SomeComponent = ({ propFromRedux }) => (
  <div>{propFromRedux}</div>
);

export { SomeComponent }; // <-- notice named export here, without redux

export default connect(state => {
  propFromRedux: stage.get(...),
})(SomeComponent);

Then in Storybook we can import the named one, not connected to Redux, and provide the propFromRedux by hand. Similar for react-router and withRouter()

@bdobry
Copy link
Author

bdobry commented Aug 3, 2020

@shilman Alright, I think I managed to fix my issue. It was incorrect babel config in the root of my project. I also needed to add @babel/preset-react. Working config for me is:

// webpack.config.js 

...
rules: [{
	test: /\.(js)x?$/,
	use: {
	  loader: "babel-loader"
	}
}]
...
// babel.config.js

module.exports = function(api) {
  api.cache(true);

  const presets = ["@babel/preset-react"];

  return {
    presets
  };
};

then this works just fine:

// preview.js

import React from "react";

export const decorators = [
  store => <div style={{ textAlign: "center" }}>{store()}</div>
];

Thanks for help anyway, keep up the good work you're doing here! 😄 We can close this issue.

@shilman shilman closed this as completed Aug 3, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants