Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 514
Marian Avatar asked Oct 31 '15 18:10

Marian


People also ask

How do Webpack and Babel work together?

If Babel is a translator for JS, you can think of Webpack as a mega-multi-translator that works with all kinds of languages (or assets). For example, Webpack often runs Babel as one of its jobs. Another example, Webpack can collect all your inline CSS styles in your Javascript files and bundle them into one.

Does Babel run before Webpack?

js and . jsx files, we tell Webpack to use babel-loader which makes Webpack run these files through Babel before bundling them.


1 Answers

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

like image 122
Marian Avatar answered Oct 04 '22 05:10

Marian