Skip to content

In loose mode, static class properties are transformed to static class block #11141

@kenrick95

Description

@kenrick95

Describe the bug

Input

class Something extends React.Component<Props, State> {
  static defaultProps = {
    transitionTime: 500,
  };
  static meow = 'a';
  constructor() {
    this.something = 'a';
  }
  render() {
    return null;
  }
}

Babel with the following config

{
  "filename": "repl.tsx",
  "presets": [
    [
      "env",
      {
        "targets": "node 20",
        "modules": false,
        "loose": true
      }
    ],
    [
      "react",
      {
        "runtime": "automatic"
      }
    ],
    [
      "typescript",
      {
        "allowDeclareFields": true,
        "allowNamespaces": true
      }
    ]
  ],
  "sourceType": "unambiguous"
}

outputs:

class Something extends React.Component {
  static defaultProps = {
    transitionTime: 500
  };
  static meow = 'a';
  constructor() {
    this.something = 'a';
  }
  render() {
    return null;
  }
}

However SWC outputs

"use strict";
class Something extends React.Component {
    static{
        this.defaultProps = {
            transitionTime: 500
        };
    }
    static{
        this.meow = 'a';
    }
    constructor(){
        this.something = 'a';
    }
    render() {
        return null;
    }
}

I noticed that it will use class static block if I set the loose option to true. When I set it to false, SWC outputs the same as Babel:

"use strict";
class Something extends React.Component {
    static defaultProps = {
        transitionTime: 500
    };
    static meow = 'a';
    constructor(){
        this.something = 'a';
    }
    render() {
        return null;
    }
}

Which brings to question: why use class static block when loose mode is used? This seem to increase the output size too (like around 10 characters difference when comparing loose=true vs loose=false with compress=true + minify=true)

Image

Input code

class Something extends React.Component<Props, State> {
  static defaultProps = {
    transitionTime: 500,
  };
  static meow = 'a';
  constructor() {
    this.something = 'a';
  }
  render() {
    return null;
  }
}

Config

{
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "tsx": true
    },
    "loose": true,
    "minify": {
      "compress": false,
      "mangle": false
    },"transform": {
    },
    "experimental": {
      "emitIsolatedDts": false
    }
  },
  "module": {
    "type": "commonjs"
  },
  "minify": false,
  "isModule": true,
  "env": {
    "targets": "node 20"
  }
}

Link to the code that reproduces this issue

https://play.swc.rs/?version=1.13.20&code=H4sIAAAAAAAAA02OzQrCQAyE74LvkFsVSunFi3%2BXvoBYX2DZRruwm5RNFgXpu9tWrL0MYeabMNYbEag5oLaOHoAvRWoErmisFhWHjglJj5fIneRQq1E8w3u9ApDhdhYavJvkdQLg9I0ANBoSp47p5gLuYVeW%2BZj0h0U1ID%2BHSmayybVMojFZ5bjZzo9aJ4XM%2B%2F50P0ocxuKCjqgpElDy%2Fgf1H6ycH1zjAAAA&config=H4sIAAAAAAAAA4VSTWuDQBS8%2ByvknSOE0lNuJXooJVhsj0LZ6lM27Ifs25SI%2BN%2F7tGpMadI97c7Mm2VntgvCEI5UwC7seMuHRjhCt5wZodZ4cWYEfNsgFU42HjYz62mgvDvhiPQ%2FBChrCSdigrQ0smrXzoXVjUMixiqhCBdTLUytcIYnY%2FBOGKqs0yuP34s9DfmDLU8K6Y6OlbWyn2x%2FVzQ832qM0DnrosKW%2BI%2BcB5IsS7OPfRonb0NoXQ7pSw677SaHOHnNkv3TexIzED32S4x%2Frf4md4vpryrAc4NOauT21Dp11NI%2Fk1XCYxl7uk45mOZBjxFe%2FsXQ%2FfAc7kxbcyS4KOdelw5B0mEenz8AoPlauQlX43g3GA41fNiOfkH%2FDQMdUx%2BRAgAA

SWC Info output

N/A uses playground (1.13.20)

Expected behavior

When using loose = true, shouldn't transform static class property to static block

Actual behavior

When using loose = true, it transform static class property to use static block

Version

1.13.20

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions