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

Decorators syntax usage is broken #6069

Closed
darkowic opened this issue Mar 13, 2019 · 24 comments
Closed

Decorators syntax usage is broken #6069

darkowic opened this issue Mar 13, 2019 · 24 comments

Comments

@darkowic
Copy link

Describe the bug
When trying to write a story that contains code using decorators syntax (In this case Mobx - the decorators works totally fine in the project) it throws an error:

index.js:39 Error: Decorating class property failed. Please ensure that proposal-class-properties is enabled and set to use loose mode. To use proposal-class-properties in spec mode with decorators, wait for the next major version of decorators in stage 2.

The babel configuration in .babelrc is correct, the file is read:

{
  "plugins": [
    "@babel/plugin-syntax-dynamic-import",
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
    ["@babel/plugin-proposal-class-properties", { "loose": true }],
    "babel-plugin-styled-components",
    "@babel/plugin-proposal-export-default-from",
    "@babel/plugin-transform-async-to-generator",
    "@babel/plugin-transform-classes",
    "@babel/plugin-transform-runtime"
  ],
  "presets": [
    [
      "@babel/preset-env",
      {
        "useBuiltIns": "entry",
        "modules": false
      }
    ],
    "@babel/preset-react"
  ],
}

To Reproduce
Steps to reproduce the behavior:

  1. Create story using the decorator
  2. Try open it - error in the console

Expected behavior
Decorators can be used.

System:

  • OS: Ubuntu
  • Framework: react
  • Addons: [actions, viewport]
  • Version: 5.0.1
@pgoforth
Copy link
Contributor

This likely has to do with legacy implementation of @babel/plugin-proposal-decorators. I'm working on a project using the latest decorator proposal and everything works fine:

['@babel/plugin-proposal-decorators', {
    legacy: false,
    decoratorsBeforeExport: false,
    version: 'jan-2019'
}]

@darkowic
Copy link
Author

I've tried to set up this and I got another error:

Error: [mobx] Incorrect decorator invocation. @observable decorator doesn't expect any arguments

Can not use the new decorator's implementation because of mobxjs/mobx#1352.

@mweststrate maybe you have a solution for this one?

@mweststrate
Copy link

legacy should be true. Beyond that, share setup and example or didn't happen.

@darkowic
Copy link
Author

There you go - https://github.com/darkowic/storybook-mobx-decorators-example

I was able to reproduce it in react-create-app based example.

Thanks!

@mweststrate
Copy link

mweststrate commented Mar 14, 2019

@darkowic this is not what maintainers typically call a minimal reproduction ;-). Can you link to the babel config in that repo?

Edit: or is a blank storybook that large? Sorry, zero experience with storybook, just wanted to peek at the babel config to see if there is something obvious

@darkowic
Copy link
Author

Well :D Actually what I post in the first commit is IMHO the minimal babelrc config that reproduces the problem.

In the repo is only ejected CRA, initiated storybook with https://github.com/storybooks/storybook/tree/next/app/react and added babel config to package.json

  "babel": {
    "plugins": [
      [
        "@babel/plugin-proposal-decorators",
        {
          "legacy": true
        }
      ],
      [
        "@babel/plugin-proposal-class-properties",
        {
          "loose": true
        }
      ]
    ],
    "presets": [
      "react-app"
    ]
  }

The actual code that reproduces it is in src/stories/index.js and it is simply:

class Test {
  @observable x = 1
}

const xxx = new Test();

There have to be something with storybook internals, I guess. Probably MobX itself is doing nothing wrong here. I ping you after @pgoforth comment because I thought that maybe you've seen similar case before. Let's wait for some maintainers answer @shilman

@mweststrate
Copy link

Looks superficially fine (assuming it is using babel 7, not 6). Maybe the config is not picked up at all from that place? Anyway, leaving it to the storybook maintainers for now... :)

@darkowic
Copy link
Author

I forgot about it - storybook does not read config from package.json but it does read from .babelrc - https://storybook.js.org/docs/configurations/custom-babel-config/

I've updated the example. The issue still there.

@pgoforth
Copy link
Contributor

pgoforth commented Mar 14, 2019

@darkowic
I don't know what to tell you. I can use decorators on static properties in my codebase and everything works fine in Storybook. However, I am not using Mobx and I am using the latest decorators spec. This seems like more of an incompatibility between Mobx (or a dependency thereof) and Storybook.

I did notice one thing. When using @babel/plugin-proposal-class-properties in loose mode, it does not use Object.defineProperty. That may have some bearing on the effectiveness of decorators, since they are used for modifying property descriptors. Hopefully this leads you in the right direction, but like @mweststrate implied, without code to test against, we can only guess what's causing the issue.[Update] Looking through your repo now

@mweststrate
Copy link

@darkowic note that error in the screenshot actually signals that it should be in loose mode, which is also in your config, which seems to suggest the config isn't actually picked up? MobX requires loose mode, that is correct. It seems that that is what storybook expects as well from the above message.

(loose mode is also the typescript behavior, and with loose mode it is easier to change descriptors with decorators, which is harder in strict mode, which seems to be a problem with the spec that sadly not everybody agrees upon, but it's on hold now anyway)

@darkowic
Copy link
Author

The config is picked. When I break anything in the babel config, storybook will throw that cannot read the config.

@pgoforth
Copy link
Contributor

@darkowic
When I use this in your babel config in that test repo, the error is gone:

{
  "plugins": [
    [
      "@babel/plugin-proposal-decorators",
      {
        "legacy": false,
        "decoratorsBeforeExport": false,
        "version": "jan-2019"
      },
    ],
    [
      "@babel/plugin-proposal-class-properties",
      {
        "loose": true
      }
    ]
  ],
  "presets": [
    "react-app"
  ]
}

I realize you need to use legacy decorators, but maybe there's a different legacy config that will work for you.

@shilman
Copy link
Member

shilman commented Mar 15, 2019

You guys are awesome, not sure what to add here. I'm working on some tools/process for debugging webpack issues right now #6081. Hopefully it will help but this is fundamentally complex stuff 😦

@pgoforth
Copy link
Contributor

@shilman @darkowic @mweststrate
Seems this is an issue with Babel
babel/babel#7373

@aaronchenwei
Copy link

aaronchenwei commented Mar 26, 2019

Just met the same issue with create-react-app created React projects.

The issue is about the order of overriding options passed to babel-loader. If it is a create-react-app project, @storybook/react would detect if react-scripts is present. If yes, it will load the options from react-scripts package. As you might know, react-scripts from create-react-app has configured babel options as below.

{
  "plugins": [
    ["@babel/plugin-proposal-decorators"],
    ["@babel/plugin-proposal-class-properties", { "loose" : true }],
  ]
}

The default option for @babel/plugin-proposal-decorators is with legacy flag false.

The babel configuration from react-scripts come after customized storybook .babelrc. That is why .babelrc from storybook is not picking the legacy flag.

The work-round for me is to eject create-react-app project for now. After ejection, react-scripts is no longer there.

@stale
Copy link

stale bot commented Apr 16, 2019

Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks!

@stale stale bot added the inactive label Apr 16, 2019
@stale
Copy link

stale bot commented May 16, 2019

Hey there, it's me again! I am going close this issue to help our maintainers focus on the current development roadmap instead. If the issue mentioned is still a concern, please open a new ticket and mention this old one. Cheers and thanks for using Storybook!

@stale stale bot closed this as completed May 16, 2019
@tylernotfound
Copy link

@darkowic I can't tell if you found the solution to your issue, but I was experiencing the same problem.

After struggling for a while, I found this comment babel/babel#8577 (comment) which helped lead me to the solution that worked for me.

Adding the plugins to .babelrc was not enough. I needed to create a custom .storybook/webpack.config.js and add the plugins there. Once I had the custom webpack config, the error was gone and the stories were working properly.

@darkowic
Copy link
Author

FYI: Storybooks 5.1 solved the issue in my project. Though, I did not test it in the repository I created.

@x2es
Copy link

x2es commented Nov 22, 2019

I have got a solution 😄

Try add to .storybook/webpack.config.js

module: {
  rules: [
    {
      test:    /\.jsx?$/,
      exclude: /(node_modules)/,
      use:     'babel-loader',
    },
  ]
}

After this common babel config got applied.

@x2es
Copy link

x2es commented Nov 22, 2019

@pgoforth

Should it be in place in default .storybook/webpack.config.js?
Initial setup of mine .storybook was made by teammate, so I don't know exact reason why babel-loader was absent.

@richardwardza
Copy link

I'm also using create-react-app, mobx and storybook and having issues with decorators.

I managed to get around this by having duplicate .babelrc files.
The first babelrc is in my root directory contianing:

{
  "plugins": [
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
    ["@babel/plugin-proposal-class-properties", { "loose" : true }],
    "babel-plugin-styled-components"
  ],
  "presets": [
    "babel-preset-react-app"
  ]
}

The second .babelrc file I put in my .storybook directory looks like:

{
  "plugins": [
    ["@babel/plugin-proposal-decorators", { "legacy": true }, "p1"],
    ["@babel/plugin-proposal-class-properties", { "loose" : true }, "p2"],
    ["babel-plugin-styled-components", {},  "p3"]
  ],
  "presets": [
    ["babel-preset-react-app", {}, "p4"]
  ]
}

I had to give everything alias name so it didn't clash with the root level babelrc.

So far things look good....

@Jeslopov
Copy link

I'm also using create-react-app, mobx and storybook and having issues with decorators.

I managed to get around this by having duplicate .babelrc files.
The first babelrc is in my root directory contianing:

{
  "plugins": [
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
    ["@babel/plugin-proposal-class-properties", { "loose" : true }],
    "babel-plugin-styled-components"
  ],
  "presets": [
    "babel-preset-react-app"
  ]
}

The second .babelrc file I put in my .storybook directory looks like:

{
  "plugins": [
    ["@babel/plugin-proposal-decorators", { "legacy": true }, "p1"],
    ["@babel/plugin-proposal-class-properties", { "loose" : true }, "p2"],
    ["babel-plugin-styled-components", {},  "p3"]
  ],
  "presets": [
    ["babel-preset-react-app", {}, "p4"]
  ]
}

I had to give everything alias name so it didn't clash with the root level babelrc.

So far things look good....

@richardwardza Tried every solution around and yours is the only one that worked for me, Thaks a Lot!!

@Muneeb-Mohd
Copy link

Can someone help me with this same issue please? I'm using CRA with react-app-rewired. The config files are as follows.

.storybook/main.js

module.exports = {
  stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
  addons: [
    '@storybook/addon-links',
    '@storybook/addon-essentials',
    '@storybook/preset-create-react-app',
    'storybook-addon-material-ui',
  ],
  reactOptions: {
    fastRefresh: true,
    strictMode: true,
  },
  typescript: { reactDocgen: 'react-docgen' },
};

config-override.js

import { removeModuleScopePlugin } from 'customize-cra';

module.exports = function override(config, env) {
  if (!config.plugins) {
    config.plugins = [];
  }
  removeModuleScopePlugin()(config);

  return config;
};

I don't have bable plugin currently in my package.json file right now. Do let me know what I can do about it right now, thank you!

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

10 participants