facebook / create-react-app

Set up a modern web app by running one command.

Home Page:https://create-react-app.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Decorator is not supported!

HatemJerbi opened this issue · comments

Note from maintainers

For people coming to this thread later—if you use MobX or a similar library, you don’t need decorators. They are just syntax sugar in this case.
Learn more: #214 (comment), #411 (comment).
Here is why we don’t include them: #411 (comment).

we can not use library like mobx (@observer,@observable).
to fix this :

  • babel stage-1
  • babel "transform-decorators-legacy" plugin

Decorators are still in the very early stages of standardisation. The behaviour of them could change rapidly, without warning. Users of decorators need to be willing to adapt fast, and therefore aren't the main target for create-react-app. I don't think we should be including them in this project at this time.

I do think we should look into supporting customisation of the babel, eslint and webpack configs in some way, but that's a larger discussion.

commented

We are holding off decorators until babel supports them out of the box, for more info check out #107

commented

You can use MobX without decorators.

commented

@gaearon Don't you have to use the old React.createClass method if you do not use decorators though? It changes a lot of the code structure in your components (No constructor(), commas after every method, etc...) :-/

Would be great to be able to use create-react-app without ejecting to set babel decorator support.

var MyComponent = observer(React.createClass({ ...

https://mobxjs.github.io/mobx/best/syntax.html

commented

No, you can do this just fine:

const MyComponent = observer(class MyComponent extends React.Component {
    render() {
        // Warning: don't use {this.onButtonClick.bind(this)} or {() => this.onButtonClick} !
        return <button onClick={this.onButtonClick}>Hi</button>
    }

    onButtonClick = (e) => {
        // bound function
    }
})
commented

That works. Thank you!

I'm really surprised the mobx documentation never mentions this solution considering decorators are still experimental and not enabled by default in babel. I'll have to send them a pull request.

cc @mweststrate, I talked to him about this when we met at RuhrJS and he said he planned to remove the decorator syntax from the docs!

For people stumbling into this in the future, here is a small create-react-app based repo with MobX, without decorators:

https://github.com/mobxjs/create-react-app-mobx

@mxstbr well, not removing, but make it very clear it is optional :)

The MobX docs now have a dedicated section listing how to use or avoid using decorators. I hope that helps avoid confusion in the future! http://mobxjs.github.io/mobx/best/decorators.html

Didn't try yet, but this should allow using decorators with create-react-app without ejecting: https://www.npmjs.com/package/custom-react-scripts. Might be interesting to check out if anybody runs into this in the future.

I ended up ejecting to get decorators.

I'm primarily a c#/java dev, so I just don't understand how decorators can be at all controversial.
I mean Java got annotations over a decade ago. As an industry we've got a pretty clear understanding of good syntax and how they should work. It's just one more frustration for people who are used to a mature development language coming back into the wild wild west of JavaScript.

Not your fault, but come on. How can this this still be a controversy? Coming back to JavaScript from C# has turned me into an old man who says "Back in my day we had !" all the time.

commented

A better place to discuss it @jason-henriksen would be here where decorators are being discussed upstream (babel). Until they're standardised and supported officially they probably won't be in an "official"/"endorsed" project like create-react-app for obvious reasons.

@mweststrate thanks for the comment on using custom-react-scripts. It made my eject effort unnecessary and was MUCH nicer to use than fiddling with things myself.

@tbillington thanks for the pointer to the discussion. I'm sure a noob like myself can't all that much help, but maybe there's some small way I can push that ball along. In the mean time, I'm happy with the plug-in of the legacy code that lets me get things done. Thanks again for the tip.

commented

For anyone reading this in the future, I would like to point out that the decorators spec has changed significantly. I'm really glad we made the decision to not support them at early stage, so users who didn't eject don't need to change their code.

I don't recommend anyone to rely on the legacy decorator transform (that is not part of CRA). See this thread for more info: https://twitter.com/dan_abramov/status/897491076537356288.

According to that table at the top, it says that there's no breaking change, just a new feature.

@rclai it's a bit misleading: it's not breaking in Babel's context because the linked PR is adding a totally new transform that relies on a completely different parser plugin (decorators2) than the "current" one.

The two syntaxes, as @gaearon mentioned, are definitely different, namely:

@bar
export default Foo {}

now needs to be:

export default 
@bar class Foo { }

One of our "ship-Babel-7" tasks is to provide codemods for these types of changes to help ease the transition.

Just to help anyone out: if you need to use inject with observable (without decorators) you can use it like this:

class Foo extends Component {
    /* whatever view logic here */
}
Foo = inject('key')(obserable(Foo));

Yes or you could use recompose's compose function to make it look nicer:

class Foo extends Component {
    /* whatever view logic here */
}
export default compose(
  inject('key'),
  observable
)(Foo);
commented

Use this to inject mobx decorators into config without ejecting.
https://github.com/timarney/react-app-rewired/tree/master/packages/react-app-rewire-mobx

commented

It’s not supported and will break. If you’re okay with this, cool, but please don’t teach beginners to use something that will be broken in a year.

Furthermore, the legacy decorator plugin does not even support the latest specification and your code will likely break when you update it to the recent one (which isn’t implemented by Babel at all).

I’m locking this issue. As noted above, decorators are an unstable proposal and won’t be enabled until they both advance further and there is a Babel plugin that implements the latest spec.