New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Class static properties, referenced in other static properties isn't transpiled well when using decorators. #8979

Open
andriimiroshnychenko opened this Issue Nov 6, 2018 · 7 comments

Comments

Projects
None yet
3 participants
@andriimiroshnychenko

andriimiroshnychenko commented Nov 6, 2018

Bug Report

Current Behavior
Given that I'm using decorators.
If I try to reference static properties of a class inside another static property of the same class, I will get runtime error.

Input Code
Please check here, there is a bit detailed description and steps to reproduce.
https://github.com/andriimiroshnychenko/small-repro

This repo uses MobX as a source of decorators, but I tried also another libraries and they threw same error.

Expected behavior/code
No runtime error should appear.

Babel Configuration (.babelrc, package.json, cli command)

module.exports = api => {
    api.cache(false);

    return {
        presets: [
            [
                '@babel/preset-env',
                {
                    targets: {
                        browsers: ['last 2 Chrome versions', 'last 2 Safari versions', 'last 2 Firefox versions']
                    },
                    modules: false,
                    forceAllTransforms: true
                }
            ],
            '@babel/preset-typescript'
        ],
        plugins: [
            ['@babel/plugin-proposal-decorators', { legacy: true }],
            ['@babel/plugin-proposal-class-properties', { loose: true }],
        ]
    };
};

Environment

  • Babel version(s): ^7.1.0
  • Node/npm version: Node 8.11.4/npm 5.6.0
  • OS: Ubuntu 16.04
  • Monorepo: no
  • How you are using Babel: loader
@babel-bot

This comment has been minimized.

Collaborator

babel-bot commented Nov 6, 2018

Hey @andriimiroshnychenko! We really appreciate you taking the time to report an issue. The collaborators
on this project attempt to help as many people as possible, but we're a limited number of volunteers,
so it's possible this won't be addressed swiftly.

If you need any help, or just have general Babel or JavaScript questions, we have a vibrant Slack
community that typically always has someone willing to help. You can sign-up here
for an invite.

@nicolo-ribaudo

This comment has been minimized.

Member

nicolo-ribaudo commented Nov 6, 2018

If you are only using MobX decorators you could try to disable the legacy flag.

@andriimiroshnychenko

This comment has been minimized.

andriimiroshnychenko commented Nov 6, 2018

In my small repo with this config

        plugins: [
            ['@babel/plugin-proposal-decorators'],
            ['@babel/plugin-proposal-class-properties']
        ]

I got this error

Module build failed: Error: [BABEL] /home/amiro/project/small-repro/src/index.js: The decorators plugin requires a 'decoratorsBeforeExport' option, whose value must be a boolean. If you want to use the legacy decorators semantics, you can set the 'legacy: true' option. (While processing: "/home/amiro/project/small-repro/node_modules/@babel/plugin-proposal-decorators/lib/index.js")

After enabling decoratorsBeforeExport error was changed to:

TypeError: An element descriptor's .kind property must be either "method" or "field", but a decorator created an element descriptor with .kind "undefined"

Despite this, bug is revealed in large project, where mix of different decorators exists. So It will be very helpful to get some fix/workaround to get it through with legacy: true

@nicolo-ribaudo

This comment has been minimized.

Member

nicolo-ribaudo commented Nov 6, 2018

Oh right, I thought that mobxjs/mobx#1732 was already merged.

As a workaround you can try to use this instead of TestClass inside class properties

@andriimiroshnychenko

This comment has been minimized.

andriimiroshnychenko commented Nov 6, 2018

thanks, but unfortunately with this I can reference only non-static properties, belonged to the instance of the class, not class itself. This will lead to some refactoring + will create unnecessary properties on class instances + impose constraints on development.
The point of this bug is use exactly statics inside other statics.

@nicolo-ribaudo

This comment has been minimized.

Member

nicolo-ribaudo commented Nov 6, 2018

This should work, unless Babel has also bugs regarding this (our legacy decorators implementation doesn't play well with other class proposals).

class Foo {
  static x = this;
}

Foo.x = Foo; // true
@andriimiroshnychenko

This comment has been minimized.

andriimiroshnychenko commented Nov 6, 2018

This can help if "lazy" property initialization is allowed in code. Because

class Foo {
  static x = this;
}

is meaningless in terms of assigning this to static propety, it will be compiled by Babel as

var Foo = function Foo() {
 _classCallCheck(this, Foo);
};

_defineProperty(Foo, "x", void 0);

And only after class is described, you can assign it to some own property, as you did in last line of code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment