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.

Community
  • 1
  • 1
Marian
  • 1,352
  • 4
  • 15
  • 28
  • 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. – aegyed Nov 01 '15 at 08:54
  • latest babel-core@6.9.0 seems to have this problem. Is it a regression bug? – sglai May 20 '16 at 20:36
  • @sglai apart from not being very specific from your part, I am on babel-core@6.9.0 and my code compiles fine not having changed much since. Please refer to phabricator or open a new issue. – Marian May 21 '16 at 17:05

6 Answers6

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.)

Community
  • 1
  • 1
Marian
  • 1,352
  • 4
  • 15
  • 28
  • 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... – Micros Feb 10 '16 at 16:36
  • 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). – Marian Feb 10 '16 at 19:38
  • 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: http://stackoverflow.com/a/34210231/270968 – Micros Feb 11 '16 at 08:52
11

Try to replace your export with such construction:

class SurveyForm extends Component {/*implementation*/}
export default SurveyForm
Stryzhevskyi
  • 121
  • 6
  • 1
    This is mentioned as a workaround for a [confirmed bug in 6.0.14](https://github.com/babel/babel/issues/2700) 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. – Marian Nov 01 '15 at 19:43
  • @Marian did you find a fix for the "Missing class properties transform" bug ? – redmoon7777 Nov 04 '15 at 00:28
  • 4
    @redmoon7777 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. – Marian Nov 06 '15 at 00:58
  • 2
    Preset order is _very_ important. I had stage-0 first, had to move it last and es2015 first. – Sergiu Paraschiv Dec 28 '15 at 20:45
  • 1
    For any future readers, just wanted to confirm that what @SergiuParaschiv said is correct. Set es2105 first, and put stage last. – Chris Apr 13 '16 at 12:36
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

babel-core@6.3.17
babel-loader@6.2.0
babel-plugin-react-transform@2.0.0-beta1
babel-preset-es2015@6.3.13
babel-preset-react@6.3.13
babel-preset-stage-0@6.3.13

That works for me.

Christine
  • 3,014
  • 2
  • 24
  • 34
  • 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. – Marian Dec 17 '15 at 02:57
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

David
  • 93
  • 7
1

Have you tried?:

presets: [{
    plugins: [
        'transform-class-properties'
    ]
}, 'stage-0', 'es2015', 'react']
Dominic
  • 62,658
  • 20
  • 139
  • 163
  • Yes tried and didn't make a difference in the end wherever I put it. – Marian Nov 03 '15 at 01:28
  • Just to add though - you can't use this before calling super in the constructor, that's normal – Dominic Nov 03 '15 at 08:02
  • 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. – Marian Nov 03 '15 at 21:18
  • There is no concept of 'this' until the constructor is called and the instance is created, perhaps the compiler was fixing the code – Dominic Nov 03 '15 at 21:20
  • [Actually the 'this before super error' appears to be yet another issue in Babel6](https://github.com/babel/babel/issues/2774#issuecomment-154214356) – Marian Nov 06 '15 at 01:02
  • @Marian 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: http://www.2ality.com/2015/02/es6-classes-final.html#super-constructor_calls – Dominic Nov 06 '15 at 09:45
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

sajinshrestha
  • 735
  • 1
  • 6
  • 11
  • 1
    If you look at the documentation for the stage-0 preset https://babeljs.io/docs/plugins/preset-stage-0/ - it states that it also includes all plugins from presets 1, 2, and 3. – danecando Nov 11 '15 at 19:52
  • 1
    @danecando I missed 'all the plugins' part. Thank you. Still trying to figure out how babel 6 works. – sajinshrestha Nov 11 '15 at 21:20
  • 2
    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. -_- – danecando Nov 11 '15 at 22:30
  • 1
    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. – Marian Nov 12 '15 at 03:47