Parcel: ๐Ÿ› Can't add more presets to .babelrc (Merge defaults with babelrc file problem)

Created on 20 Feb 2018  ยท  25Comments  ยท  Source: parcel-bundler/parcel

From 1.5.1 to 1.62 I cannot get rid of "Missing class properties transform" when using stage-2 preset. It seems that under some situations the babelrc gets ignored (or that "env", "react" presets are locked)

๐ŸŽ› Configuration (.babelrc, package.json, cli command)

I am using --no-cache all the time so deleting the cache is not an applicable workaround for my case.

babel

{
  "presets": ["env", "react", "stage-2"]
}

package

{
  "name": "ui",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "scripts": {
    "start": "parcel src/index.html --no-cache",
    "build": "parcel build src/index.html --no-cache"
  },
  "dependencies": {
    "react": "^16.2.0",
    "react-dom": "^16.2.0",
    "react-redux": "^5.0.7",
    "react-router-dom": "^4.2.2"
  },
  "devDependencies": {
    "babel-preset-env": "^1.6.1",///with or without it
    "babel-preset-react": "^6.24.1",///with or without it
    "babel-preset-stage-2": "^6.24.1",
    "parcel-bundler": "^1.6.2"
  }
}

๐Ÿค” Expected Behavior

Babel should respect my babel config and include all the transformations that this preset should add.

๐Ÿ˜ฏ Current Behavior

Babel seems to ignore my config and still errors with "Missing class properties"

๐Ÿ’ Possible Solution

I tried to read the codebase, but i don't know it too well. However I suspect it related to a pkg constructor param which seems to block the reading of the babel file under some circusntamces.

๐Ÿ”ฆ Context

I just want to use transform class properties syntax

๐Ÿ’ป Code Sample

import React from 'react'

class Root extends React.Component {
    state = { time: 0 }//errors here

    render() {
        return 'hi from react ' + this.state
    }
}

export default Root

๐ŸŒ Your Environment

| Software | Version(s) |
| ---------------- | ---------- |
| Parcel | from 1.5.1 to 1.6.2
| Node | 8.9.2
| npm/Yarn | 1.2.1
| Operating System | windows 10 (and ubuntu 16.04 only parcel 1.6.2)

I think this is related to https://github.com/parcel-bundler/parcel/issues/824 and https://github.com/parcel-bundler/parcel/issues/824

Bug babel โœจ Parcel 2

Most helpful comment

I've run into the same problem with
.babelrc:

{
  "presets": ["env", "stage-2", "react"],
}

and compiled success after adding "plugins": ["transform-class-properties"]
.babelrc:

{
  "presets": ["env", "stage-2", "react"],
  "plugins": ["transform-class-properties"]
}

All 25 comments

According to the babel docs, you need a separate transform-class-properties plugin.

See: Babel Class-Properties-Transform Docs

In my attempts to reproduce this I actually wasnโ€™t able to get the Babel plugin working for some reason... but that seems to be an issue with Babel itself (I even got the error when I ran Babel without Parcel)

@davidnagli stage-2 should include that plugin already

You should only need transform-class-properties if you're using stage-3 to my knowledge.

@lrn2prgrm can you post the exact error as well as your full .babelrc?

My first thought is that perhaps the plugins are not being applied in the proper order. Have you previously built this project using webpack or some other library?

There is some logic here which filters out presets already applied by babel-preset-env. stage-X presets are not in the list though, so I'm a not exactly sure what's going on. That's the place to look though, if someone wants to take this on.

https://github.com/parcel-bundler/parcel/blob/0d9d14cbda742e612b36f5c37db55e45a7a1ff1e/src/transforms/babel.js#L98-L103

@Slapbox that's my full .babelrc
About devon's reply that's definetly the place to look. I commented a portion of that code (as adviced by @devongovett ) and got everything working (although it might be breaking some other functionality). The lines i commented are: 97 to 114 in node_modules/parcel-bundler/src/transforms/babel.js

You could log the generated babelrc in that function after the filtering occurs to debug.

@lrn2prgrm I think I was mistaken before, mixing up plugins and presets. If you want to give this a try:


.babelrc

{
  "presets": ["env", "react", "stage-2"],
  "plugins": [ "transform-class-properties",  "transform-es2015-classes",]
}

Just be sure to actually install those plugins first.

JSON.stringify(babelrc)

parcel bundler code

{
    "presets": [
        "react",
        "stage-2"
    ],
    "plugins": [
        [null,
            {
                "spec": false,
                "loose": false
            }
        ],
        [null,
            {
                "spec": false,
                "loose": false
            }
        ],
        [null,
            {
                "spec": false,
                "loose": false
            }
        ],
        [null,
            {
                "spec": false,
                "loose": false
            }
        ],
        [null,
            {
                "spec": false,
                "loose": false
            }
        ],
        [null,
            {
                "spec": false,
                "loose": false
            }
        ],
        [null,
            {
                "spec": false,
                "loose": false
            }
        ],
        [null,
            {
                "spec": false,
                "loose": false
            }
        ],
        [null,
            {
                "spec": false,
                "loose": false
            }
        ],
        [null,
            {
                "spec": false,
                "loose": false
            }
        ],
        [null,
            {
                "spec": false,
                "loose": false
            }
        ],
        [null,
            {
                "spec": false,
                "loose": false
            }
        ],
        [null,
            {
                "spec": false,
                "loose": false
            }
        ],
        [null,
            {
                "spec": false,
                "loose": false
            }
        ],
        [null,
            {
                "spec": false,
                "loose": false
            }
        ],
        [null,
            {
                "spec": false,
                "loose": false
            }
        ],
        [null,
            {
                "spec": false,
                "loose": false
            }
        ],
        [null,
            {
                "spec": false,
                "loose": false
            }
        ],
        [null,
            {
                "spec": false,
                "loose": false
            }
        ],
        [{
                "__esModule": true
            },
            {
                "spec": false,
                "loose": false
            }
        ],
        [null,
            {
                "spec": false,
                "loose": false
            }
        ],
        [null,
            {
                "spec": false,
                "loose": false
            }
        ],
        [null,
            {
                "spec": false,
                "loose": false
            }
        ]
    ]
}

commenting code (devon temporal hack)

{"presets":["env"
"react"
"stage-2"]}

Where's that being output? I don't see env in there.

The plugins in there are the plugins corresponding to preset-env. stage-2 is in there, so not sure why babel wouldn't apply it...

Anyone manage to resolve this? I have the same issue with parcel 1.6.x. And adding the plugins manually changed nothing. The same babel conf seems to work for babel-jest and for webpack

@devongovett I think this is because the order of plugins and presets matters:

This:

{
  "presets": ["env", "stage-2"]
}

means that stage-2 will be applied first and afterwards env.

Plugins run before presets (https://babeljs.io/docs/plugins/#pluginpreset-ordering), so

{
  "presets": ["env", "stage-2"],
  "plugins": ["transform-class-properties"]
}

will first run transform-class-properties, then stage-2 and then env.

But I think the way that parcel modifies the config (translating env into the individual plugins - why are we even doing that, avoiding a new dependency in the project itself?) breaks that order:

{
  "presets": ["stage-2"],
  "plugins": [/*all the indivial plugins from "env"*/]
}

will behave the same as

{
  "presets": ["stage-2", "env"]
}

which isn't what we want? (env is somehow always the first entry).
I'm guessing, that the error stems from some env plugin, which can't handle static class properties.

Commenting out only https://github.com/parcel-bundler/parcel/blob/eaf51d01462b353aeaf78ebe80d797477ae1938d/src/transforms/babel.js#L114
fixes the error (but of course no env plugins are applied because "plugins": [/*all the indivial plugins from "env"*/] isn't added to the config).

EDIT:
Specifying the plugin explicitly works because it will be the first plugin listed

{
  "presets": ["stage-0"],
  "plugins": ["transform-class-properties", /*...*/]
}

and Plugin ordering is first to last.

@kaitk Do you mean that

{
  "presets": ["env", "react"],
  "plugins": ["transform-class-properties"]
}

doesn't work either? (or whatever plugin and framework you need).

Unfortunately none of the .babelrc examples here seem to work for me (even when playing with the order). ["env", "react"] alone won't work, as the codebase uses the spread operator extensively (and then that fails because of that). If I add that plugin manually, I still get an error, with the .bablerc looking like the following:

{
  "presets": ["env", "react"],
  "plugins": ["transform-class-properties", "transform-object-rest-spread"]
}

I guess the class property thing might actually work for my own codebase (I'm not sure in the processing order of parcel though to be sure), but it definitely fails for dependencies. I get the following error in react-redux-toastr:

.../node_modules/react-redux-toastr/src/ReduxToastr.js:13:21: Unexpected token (13:21)
  11 |
  12 | export class ReduxToastr extends React.Component {
> 13 |   static displayName = 'ReduxToastr';
     |                      ^
  14 |

I get the following error with both "stage-x" or manually adding "transform-class-properties". (and as I mentioned, the same project setup works with babel-jest and webpack)

I've run into the same problem when using parcel-bundler with babel-preset-react-app.

package.json:

"babel-preset-react-app": "^3.1.1",
"cross-env": "^5.1.3"

.babelrc:

{
  "presets": ["react-app"]
}

Getting Missing class proper error.

I've run into the same problem with
.babelrc:

{
  "presets": ["env", "stage-2", "react"],
}

and compiled success after adding "plugins": ["transform-class-properties"]
.babelrc:

{
  "presets": ["env", "stage-2", "react"],
  "plugins": ["transform-class-properties"]
}

It seems that my issue is related to the babel config of a dependency project. I created a sample failing project: https://github.com/kaitk/parcel_bug

As the Readme mentions, class properties in my own files (Root.jsx) work, but only when the "transform-class-properties" plugin is added manually.

"react-redux-toastr" still won't build regardless.

@devongovett would you be open to transforming spread by default?

The spread operator is standard now in node and evergreen browsers and is massively useful for immutable code. Not being able to use spread in parcel either forces you to add a babel config or go through your code replacing spread with cumbersome Object.assigns.

I love parcel and would be happy to make a PR.

That would be treating the symptoms instead of the underlying issue (which might be https://github.com/parcel-bundler/parcel/issues/867#issuecomment-369989672 ?).

When should we start making transform-class-properties default as well?

The best thing about parcel is that it doesn't need config, it has all the sensible stuff built in. Class properties seem a less obvious choice since it isn't actually supported widely by browsers yet, as far as I know.

I might open a new issue because I think this is a distinct problem from the not reading babelrc bug. I only chose to write here because the "Spread operator in node_module causes bundling failure" issue was closed for this one.

Commenting certain part of the code it is not working for me anymore...
This bug should be top priority to be solved it is very annoying :( (can't do react without transform class properties)

any workaround for now?

{
  "plugins": ["transform-class-properties"],
  "presets": ["react-app"]
}

This works for me.

Have a similar issue with spread operator in a node module:

$ ./node_modules/parcel-bundler/bin/cli.js ./index.html --no-cache
Server running at http://localhost:1234
parcel-test/node_modules/pwa-helpers/lazy-reducer-enhancer.js:37:8:
Unexpected token (37:8)
  35 |       const nextStore = nextCreator(origReducer, preloadedState);
  36 |       return {
> 37 |         ...nextStore,
     |         ^
  38 |         addReducers(newReducers) {
  39 |           this.replaceReducer(combineReducers(lazyReducers = {

Babel preset is installed and working fine with object spreading in the project code.
Any suggestions here?

Any news about this issue? I encounter the same problem with my babel config :/

Parcel 2 will no longer merge .babelrc with a default config for babel-preset-env. Instead, .babelrc will override the default config.

Was this page helpful?
0 / 5 - 0 ratings