babeljsbabel-plugin

Prevent babel class properties plugin from overwriting my generated constructor


Overview

I have written a babel plugin that adds a custom constructor to classes. I also use the @babel/plugin-proposal-class-properties plugin to support class properties. My .babelrc looks like this:

{
  "plugins": [
    "./plugins/my-plugin.js",
    "@babel/plugin-proposal-class-properties",
  ]
}

I'm using babel-core@7.2.2, and @babel/plugin-proposal-class-properties@7.2.3.

The issue

The class properties plugin overwrites my generated constructor. For example, given this test file:

// Source
class Test extends Base {
    // someProp = 'yay';
}

If I run without the class properties plugin, my constructor is inserted:

// Transpiled (no class props)
class Test extends Base {
    constructor() {
        super(...arguments);

        console.log('my special custom code');
    }
}

But if I uncomment someProp and enable the class properties plugin, my custom code is overwritten:

// Transpiled (with class props)
class Test extends Base {
    constructor(...args) {
        super(...args);

        _defineProperty(this, "someProp", 'yay');
    }
}

It doesn't seem to matter what order I list the plugins. Is this expected, is there a way around it, or is this a bug?

I don't think the implementation of my plugin matters - but if it does, I can add more detail.

Any help appreciated. Thanks!


Solution

  • I ended up asking for help in the Babel slack community, and they were able to help me fix this issue.

    The problem was that I was using a different visitor in my implementation - I had visitors specified for ClassDeclaration and ClassMethod, but the visitor in the plugin-proposal-class-properties implementation was on Class. When I changed my code to work off of Class, and made sure mine ran first, the properties were added to my custom constructor as expected.