Skip to content
New issue

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

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

Already on GitHub? # 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
# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

No branches or pull requests

2 participants