How to set up Babel 6 stage 0 with React and Webpack
Asked Answered
B

6

52

My understanding from the docs

I see that Babel 6 has three presets for now: es2015, react and stage-x. I read that I can set those in .babelrc like so:

{
  "presets": ["es2015", "react", "stage-0"]
}

or directly in package.JSON like so:

{
  ...,
  "version": x.x.x,
  "babel": {
    "presets": ["es2015", "react", "stage-0"]
  },
  ...,
}

I can further use babel-loader with webpack like this:

loader: 'babel?presets[]=es2015'


My problem

So to compile everything nice and clean I'm adding babel-loader, which has just been updated to work with Babel6, to the webpack config like this:

module.exports = function(options) {
  var jsLoaders = ['babel?presets[]=es2015'];
  [...]
    loaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loaders: jsLoaders
      },
      {
        test: /\.jsx$/,
        exclude: /node_modules/,
        loaders: options.production ? jsLoaders : ['react-hot'].concat(jsLoaders)
      },
      [...]


Now when I compile without .babelrc in root or presets options set in package.JSON, i.e. only with the babel-loader es2015 preset set in the webpack config I get an unexpected token error about static propTypes in my React component class:

ERROR in ./app/components/form/index.jsx
Module build failed: SyntaxError: /Library/WebServer/Documents/yarsk.test/app/components/form/index.jsx: Unexpected token (19:19)
  17 | // ES6 React Component:
  18 | export default class SurveyForm extends Component {
> 19 |   static propTypes = {
     |                    ^

On GitHub I got told this is a stage-1 feature, namely transform-class-properties. So I would like to implement stage-0 right away.
BUT
When I do so by adding .babelrc or defining package.JSON like above I get a very weird build fail error:

ERROR in ./app/components/form/index.jsx
Module build failed: Error: /Library/WebServer/Documents/yarsk.test/app/components/form/index.jsx: We don't know what to do with this node type. We were previously a Statement but we can't fit in here?
    at NodePath.insertAfter (/Library/WebServer/Documents/yarsk.test/node_modules/babel-traverse/lib/path/modification.js:181:13)
    at NodePath.replaceWithMultiple (/Library/WebServer/Documents/yarsk.test/node_modules/babel-traverse/lib/path/replacement.js:92:8)
    at handleClassWithSuper (/Library/WebServer/Documents/yarsk.test/node_modules/babel-plugin-transform-class-constructor-call/lib/index.js:80:10)
    at PluginPass.Class (/Library/WebServer/Documents/yarsk.test/node_modules/babel-plugin-transform-class-constructor-call/lib/index.js:101:11)
    at newFn (/Library/WebServer/Documents/yarsk.test/node_modules/babel-traverse/lib/visitors.js:233:27)
    at NodePath._call (/Library/WebServer/Documents/yarsk.test/node_modules/babel-traverse/lib/path/context.js:72:18)
    at NodePath.call (/Library/WebServer/Documents/yarsk.test/node_modules/babel-traverse/lib/path/context.js:44:17)
    at NodePath.visit (/Library/WebServer/Documents/yarsk.test/node_modules/babel-traverse/lib/path/context.js:102:12)
    at TraversalContext.visitQueue (/Library/WebServer/Documents/yarsk.test/node_modules/babel-traverse/lib/context.js:151:16)
    at TraversalContext.visitSingle (/Library/WebServer/Documents/yarsk.test/node_modules/babel-traverse/lib/context.js:111:19)
    at TraversalContext.visit (/Library/WebServer/Documents/yarsk.test/node_modules/babel-traverse/lib/context.js:195:19)
    at Function.traverse.node (/Library/WebServer/Documents/yarsk.test/node_modules/babel-traverse/lib/index.js:139:17)
    at NodePath.visit (/Library/WebServer/Documents/yarsk.test/node_modules/babel-traverse/lib/path/context.js:106:22)
    at TraversalContext.visitQueue (/Library/WebServer/Documents/yarsk.test/node_modules/babel-traverse/lib/context.js:151:16)
    at TraversalContext.visitMultiple (/Library/WebServer/Documents/yarsk.test/node_modules/babel-traverse/lib/context.js:106:17)
    at TraversalContext.visit (/Library/WebServer/Documents/yarsk.test/node_modules/babel-traverse/lib/context.js:193:19)
    at Function.traverse.node (/Library/WebServer/Documents/yarsk.test/node_modules/babel-traverse/lib/index.js:139:17)
 @ ./app/index.jsx 9:0-28

Or in short: Module build failed: Error: /.../index.jsx: We don't know what to do with this node type. We were previously a Statement but we can't fit in here?

This is where I'm stuck. I wrote this component with Babel5 when I was able to compile with babel-loader like this and everything worked fine:

loader: 'babel?optional[]=runtime&stage=0

Now I'm getting the mentioned errors compiling.

  • Is this a babel-loader issue, or a babel issue?
  • Where do I have to configure stage-0 so that it won't throw errors?


Update

When compiling with presets set and using the mentioned workaround for the class export bug (must not export class until after creating it) the order of the set presets changes the error message. When I set stage-0 first the error now is 'this' is not allowed before super() (This is an error on an internal node. Probably an internal error) When I put stage-0 second or third I get the message about syntax error from above.


Latest

For the latest advances regarding these bugs see my post or the new babel issue tracker on phabricator for more. (Basically compiling is fixed as of 6.2.1 but there's other things happening now)

All the bugs mentioned in this article are completely fixed as of Babel 6.3.x. Please update your dependencies if you're still having issues.

Barn answered 31/10, 2015 at 18:35 Comment(3)
I have the exact same problem with gulp. I tried to configure stage-0 presets in .babelrc and also with babelify.configure, with no use.Postpone
latest [email protected] seems to have this problem. Is it a regression bug?Knowles
@Knowles apart from not being very specific from your part, I am on [email protected] and my code compiles fine not having changed much since. Please refer to phabricator or open a new issue.Barn
B
23

The two pretty heavy bugs I ran into here, namely the direct export of an ES6 class with a static property and a problem with the ES6 constructor are discussed in the answers of this thread and can be found on GitHub explicitly here (export bug) and here (constructor bug). (GitHub Issue Tracker has been closed and issues, bugs and requests have moved here.)

These are both officially confirmed bugs, fixed since Babel 6.3.17

(Maybe one or two earlier, not before 6.3.x, this is the version I'm on and everything is working as it was with Babel5. Happy coding everyone.)


(For the records:)

So if you get the following error message in the CLI:

We don't know what to do with this node type. We were previously a Statement but we can't fit in here?

Chances are you are exporting an ES6 class with a static property like this or in a similar manner (note that this doesn't seem to be connected to the class being extended anymore but rather to a class having a static property):

import React, { Component, PropTypes } from 'react'

export default class ClassName extends Component {
  static propTypes = {...}
  // This will not get compiled correctly for now, as of Babel 6.1.4
}

The simple workaround as mentioned by Stryzhevskyi and several people on GitHub:

import React, { Component, PropTypes } from 'react'

class ClassName extends Component {
  static propTypes = {...}
}
export default ClassName // Just export the class after creating it



The second issue is about the following error:

'this' is not allowed before super() (This is an error on an internal node. Probably an internal error)

Despite being a legit rule as pointed out by Dominic Tobias this is a confirmed bug where it appears that extended classes having their own properties will throw this or a similar message. As for now I have not seen any workarounds for this one. Lots of people rolled back to Babel5 for this reason for now (as of 6.1.4).

Supposedly this was fixed with the release of Babel 6.1.18 (see above GitHub issue) but people, me included, still see the same exact problem happening.


Also take note that for now the order in which you load the babel presets stage-x, react and es2015 seems to be important and may change your output.


As of Babel 6.2.1

both of these bugs are fixed, code compiles fine. But... there is still another one that probably affects a lot of people working with react, that throws ReferenceError: this hasn't been initialised - super() hasn't been called at runtime. Referenced here. Stay tuned...


Completely fixed since Babel 6.3.17

(Maybe one or two earlier, not before 6.3.x, this is the version I'm on and everything is working as it was with Babel5. Happy coding everyone.)

Barn answered 10/11, 2015 at 0:37 Comment(3)
This sounds plausible, but I've updated all babel components to 6.5.0 and it's still saying decorators are nor supported. .babelrc is pointing to stage-0, but alas...Brow
Have you tried playing around with the loading order of the presets? Loading order still changes behaviors. Furthermore the two very specific bugs from my function setup definitely are resolved, this had to do with directly exporting an extended ES6 class and the static propTypes. You may want to open another question or even better an issue on babel phabricator (link above).Barn
The order didn't make a difference, but the solution for me was in installing babel-plugin-transform-decorators-legacy and adding transform-decorators-legacy as a plugin to the .babelrc file. For more details see this answer: https://mcmap.net/q/210177/-webpack-babel-6-es6-decoratorsBrow
S
11

Try to replace your export with such construction:

class SurveyForm extends Component {/*implementation*/}
export default SurveyForm
Shoop answered 1/11, 2015 at 10:29 Comment(5)
This is mentioned as a workaround for a confirmed bug in 6.0.14 where directly exporting an extended class throws the weird error about node type. Sadly this didn't work for me. When I add all the presets to babel and move the export to the bottom I get around that but still get a syntax error about Missing class properties transform. which should be included in stage-0 from what I understand.Barn
@Barn did you find a fix for the "Missing class properties transform" bug ?Awake
@Awake try to implement the above workaround or upgrade babel to latest version and play with the presets order. I'm loading like this now: 'babel?presets[]=es2015&presets[]=react&presets[]=stage-0' so stage-0 gets loaded first and now I'm stuck with other Babel6 bugs...but for this one it helped.Barn
Preset order is very important. I had stage-0 first, had to move it last and es2015 first.Extramundane
For any future readers, just wanted to confirm that what @SergiuParaschiv said is correct. Set es2105 first, and put stage last.Hindgut
P
3

Here is a working example with Babel 6, React, Webpack and Sequelize:

https://github.com/BerndWessels/react-webpack

Basically this is the .babelrc

{
  "presets": [
    "es2015",
    "react",
    "stage-0"
  ],
  "env": {
    "development": {
      "plugins": [
        "babel-relay-plugin-loader",
        [
          "react-transform",
          {
            "transforms": [
              {
                "transform": "react-transform-hmr",
                "imports": [
                  "react"
                ],
                "locals": [
                  "module"
                ]
              },
              {
                "transform": "react-transform-catch-errors",
                "imports": [
                  "react",
                  "redbox-react"
                ]
              }
            ]
          }
        ]
      ]
    },
    "production": {
      "plugins": [
        "babel-relay-plugin-loader"
      ]
    }
  }
}

and these are the module versions

[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]

That works for me.

Perjury answered 17/12, 2015 at 0:51 Comment(1)
Thank you for your setup Christine, I didn't have time to update my article, the mentioned bugs are indeed fixed since 6.3.x and everything regarding this thread is fine. Thanks for sharing.Barn
B
2

After having the same issues, I was able to get this working with React using the below WebPack config.

module.exports = {
  entry: './app/Index.js',
  output: { path: __dirname, filename: 'dist/bundle.js' },
  module: {
    loaders: [
        {
            test: /\.js$/,
            loader: 'babel',
            query: {
                presets: ['react']
            }
        }
    ]
  }
};

I also needed to install babel-preset-react too.

npm install --save-dev babel-preset-react

EDIT: Of course you might still need to also include the ES2015 preset if you are writing ES6 as well.

Babel Presets can be found here: https://github.com/babel/babel/tree/development/packages

Bravissimo answered 1/11, 2015 at 22:18 Comment(3)
The OP is already using those presets, this is about using them with stage-0 supportShwa
As Dominic mentioned, I already load "presets": ["es2015", "react", "stage-0"] in .babelrcBarn
By doing this I got an error: "Cannot define 'query' and multiple loaders in loaders list"Noriega
S
1

Have you tried?:

presets: [{
    plugins: [
        'transform-class-properties'
    ]
}, 'stage-0', 'es2015', 'react']
Shwa answered 2/11, 2015 at 20:22 Comment(6)
Yes tried and didn't make a difference in the end wherever I put it.Barn
Just to add though - you can't use this before calling super in the constructor, that's normalShwa
I'm looking into this rule, and it's still hard for me to understand it right, since the very same code wasn't changed when upgrading to Babel6 and Babel5 didn't throw ANY errors at all. Since this doesn't connect to my original question though, I'm going to open another issue. Thank you.Barn
There is no concept of 'this' until the constructor is called and the instance is created, perhaps the compiler was fixing the codeShwa
Actually the 'this before super error' appears to be yet another issue in Babel6Barn
@Barn interesting, I realised that maybe you only need to do it in derived classes (so any react component) "In a derived class, you must call super() before you can use this:" from one of the authors of es6: 2ality.com/2015/02/…Shwa
B
0

Have you tried using just stage-1?

Using query property worked for me.

```
module: {
  loaders: [{
    test: /\.jsx?$/, 
    loader: 'babel',
    query: {
      presets: ['es2015', 'stage-1', 'react']
    }
  }]
}
```

Of course, I haven't been able to use .babelrc and babel options in package.json. Still trying to figure out babel-*v6.0

Barbed answered 11/11, 2015 at 4:52 Comment(4)
If you look at the documentation for the stage-0 preset babeljs.io/docs/plugins/preset-stage-0 - it states that it also includes all plugins from presets 1, 2, and 3.Loriloria
@Loriloria I missed 'all the plugins' part. Thank you. Still trying to figure out how babel 6 works.Barbed
Believe me @sajinshrestha, you're not alone. Between webpack & babel alone I have like 30 dependencies to get an average 'universal' react/flux app skeleton going. -_-Loriloria
The lower the number, the more features you include, every feature of the higher number is included in the next lower one. Features of stage-3 are included in stage-2 etc. Somewhat off topic, but I really found it not too hard to set up, only that this has been a major version change and I guess it's natural that there's some bugs to find and clean out.Barn

© 2022 - 2024 — McMap. All rights reserved.