Skip to content
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

keep_classnames doesn't work with var MyClass = class {} when using toplevel: true #1484

Open
janv opened this issue Jan 3, 2024 · 2 comments
Labels

Comments

@janv
Copy link

janv commented Jan 3, 2024

Bug report or Feature request?

Bug Report

Version (complete output of terser -V or specific git commit)

terser 5.26.0

Complete CLI command or minify() options used

Options:

{
  toplevel: true,
  keep_classnames: true,
  mangle: {
    keep_classnames: true
  },
}

Input:

class Foo {}
var Bar = class {}
export { Foo, Bar }

terser output or error

class Foo{}var o=class{};export{Foo,o as Bar};

Expected result

class Foo{}var Bar=class{};export{Foo,Bar};

We are using terser to minify a library meant to be used by other developers.

The fact that terser mangles the class names in the demonstrated manner makes so that users of our library will see minified classnames when inspecting objects in the dev inspector in chrome, for example. Chrome (and node, and others probably too) use the var name to assign a name to the class.

The demonstrated mangling breaks that. I would expect keep_classnames to prevent this, just as it does in the direct class definition (Foo). These statements (var X = class {}) are generated by esbuild during bundling, so we don't have much control over that.

Screenshot 2024-01-03 at 17 58 19

@janv
Copy link
Author

janv commented Jan 4, 2024

I have discovered an additional bug, that I'm not sure is related to this one.
If it's not, please let me know and I'll open a new issue.

With this config:

{
  toplevel: true,
  keep_classnames: true,
  mangle: {
    keep_classnames: true,
    reserved: ['X', 'Y']
  },
}

And this input:

var X = 'foo',
    Y = class {};

export {X}
export default Y

The output I get is

var X="foo";export{X};export default class{}

The name Y is mangled/dropped, even though it's on the reserved list and keep_classnames is on.


The issue disappears if I change the syntax of the default output:

var X = 'foo',
    Y = class {};

export {X, Y as default}

// becomes

var X="foo",Y=class{};export{X,Y as default};

// as expected

@fabiosantoscode
Copy link
Collaborator

fabiosantoscode commented Jan 16, 2024

This is very inconsistent with keep_fnames which works as you expect.

The second case is definitely valid as well, and should apply to keep_fnames too. With keep_fnames/keep_classnames, moving a class/function should either retain its .name property or not happen at all.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants