Minification removes class identifiers causing observable runtime change in Class.name
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 35/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Stale
- Tech stack
- javascript
- Domain
- build-system, tooling
Research direction
Start with the linked StackBlitz reproduction and inspect dist/main.js to confirm how the named class is transformed and how its name is observed at runtime. Review @rollup/plugin-terser's handling of class names and the documented keep_classnames workaround; done means the production output no longer causes the reported runtime difference, with regression coverage for class and constructor names.
Written by the indexing model from the issue text.
Description
- Rollup Plugin Name: @rollup/plugin-terser
- Rollup Plugin Version: 1.0.0
- Rollup Version: 4.59.0
- Operating System (or Browser): any
- Node Version: 22.19.0
- Link to reproduction: https://stackblitz.com/edit/rollup-repro-dxhgy1x9?file=dist%2Fmain.js
Description
When using @rollup/plugin-terser, named class declarations are transformed into anonymous class expressions during minification. This causes clazz.name and this.constructor.name to return an empty string ("") instead of the original class name. This results in observable runtime differences between development and production builds.
Behavior
Terser removes the class identifier and converts:
class MyClass {}
into:
class {}
This creates an anonymous class expression.
According to the ECMAScript specification:
ClassDeclaration → has a name
Anonymous ClassExpression → name === ""
Therefore:
clazz.name === ""
this.constructor.name === ""
Why This Is Problematic
This is not just cosmetic minification.
Class.name and constructor.name are frequently used for:
- logging
- debugging
- dependency injection
- metadata systems
- serialization
- runtime introspection
This creates:
- different runtime behavior in dev vs prod
- silent semantic changes
- hard-to-debug production issues
Important Note
I understand that Terser does not guarantee preservation of Function.name.
However, this transformation introduces observable semantic differences between builds, not just identifier mangling.
Workaround
Setting:
terser({ keep_classnames: true })
preserves the expected behavior.
- Dominant language
- JavaScript
- Stars
- 3.8k
- Forks
- 635
- PR merge metrics
- No merged PRs in 30d
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from rollup/plugins
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
Difficulty 4/5 3-5 days Newbie friendliness 52/100
-
Difficulty 3/5 1-2 days Newbie friendliness 48/100
-
Difficulty 4/5 3-5 days Newbie friendliness 48/100
-
Support js-yaml v5 Open
Difficulty 4/5 3-5 days Newbie friendliness 45/100
Similar issues
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
avniproject/avni-client#2135 ·
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
babalae/bettergi-scripts-list#3674 ·
-
A-Release-Notes C-Editing D-Modest S-Ready-For-Implementation
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
bevyengine/bevy-website#2595 ·
-
ecosystem wording
Difficulty 1/5 Under an hour Newbie friendliness 90/100
matrix-org/matrix.org#3649 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
vadimdemedes/ink#1029 ·