Skip to content

Conversation

@Boshen
Copy link
Member

@Boshen Boshen commented Aug 6, 2025

For the record, here's the whole process:

TypeScript ES2022 + useDefineForClassFields = false transforms

(Note Oxc has the exact same transform)

class C {
  static f = side_effect();
}

into

class C {
  static {
    this.f = side_effect();
  }
}

then babel @babel/plugin-transform-class-static-block transforms to

(Note Oxc has the exact same transform)

class C {
  static #_ = this.f = side_effect();
}

and the minifier remove unused code trims it down to

this.f = side_effect();

To eliminate this bug, we will temporary keep all classes that have static properties + side effect initializer.

i.e.

class C {
  static #_ = this.f = side_effect();
}

does not get trimmed down to this.f = side_effect().


Also note, this came from a project with a tsconfig

"useDefineForClassFields": false
  • browserslist target ios 16 where ES2022 @babel/plugin-transform-class-properties is off and ES2022 @babel/plugin-transform-class-static-block on.

@github-actions github-actions bot added A-minifier Area - Minifier C-bug Category - Bug labels Aug 6, 2025
Copy link
Member Author

Boshen commented Aug 6, 2025


How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • 0-merge - adds this PR to the back of the merge queue
  • hotfix - for urgent hot fixes, skip the queue and merge this PR next

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@codspeed-hq
Copy link

codspeed-hq bot commented Aug 6, 2025

CodSpeed Instrumentation Performance Report

Merging #12848 will not alter performance

Comparing 08-06-fix_minifier_keep_classes_that_may_have_side_effects (44b37f7) with main (5f74a0b)

Summary

✅ 34 untouched benchmarks

@Boshen Boshen marked this pull request as draft August 6, 2025 11:21
@Boshen Boshen force-pushed the 08-06-fix_minifier_keep_classes_that_may_have_side_effects branch from 116d581 to e3022ab Compare August 6, 2025 12:28
@Boshen Boshen changed the title fix(minifier): keep classes that may have side effects fix(minifier): keep classes that have static initializer that have side effects Aug 6, 2025
@Boshen Boshen changed the title fix(minifier): keep classes that have static initializer that have side effects fix(minifier): keep classes with static properties + side effect initializer Aug 6, 2025
@Boshen Boshen marked this pull request as ready for review August 6, 2025 14:49
@graphite-app
Copy link
Contributor

graphite-app bot commented Aug 6, 2025

Merge activity

…ializer (#12848)

For the record, here's the whole process:

[TypeScript ES2022 + useDefineForClassFields = false](https://www.typescriptlang.org/play/?useDefineForClassFields=true&noUnusedLocals=true&noUnusedParameters=true&experimentalDecorators=true&emitDecoratorMetadata=true&target=9&jsx=0&module=0&stripInternal=false&isolatedModules=false&verbatimModuleSyntax=false&allowSyntheticDefaultImports=true&isolatedDeclarations=false&noCheck=false&lib=true&ts=5.9.2&filetype=ts#code/MYGwhgzhAEDC0G8BQ1oQC5nQS2NAZtALyIC+A3EqUA) transforms

(Note Oxc has the exact same transform)

```js
class C {
  static f = side_effect();
}
```

into

```js
class C {
  static {
    this.f = side_effect();
  }
}
```

then babel [@babel/plugin-transform-class-static-block](https://babel.dev/repl#?corejs=3.21&spec=true&code_lz=MYGwhgzhAEDC0G8BQ1XQgFzBglsR0GAFjhAHQBm0AvIgL4Dc0dSdQA&forceAllTransforms=true&modules=commonjs&timeTravel=true&sourceType=module&lineWrap=true&presets=react%2Ctypescript&version=7.26.1&externalPlugins=%40babel%2Fplugin-transform-class-static-block%407.27.1) transforms to

(Note Oxc has the exact same transform)

```js
class C {
  static #_ = this.f = side_effect();
}
```

and the minifier remove unused code trims it down to

```js
this.f = side_effect();
```

---

To eliminate this bug, we will temporary keep all classes that have static properties + side effect initializer.

i.e.

```js
class C {
  static #_ = this.f = side_effect();
}
```

does not get trimmed down to `this.f = side_effect()`.

---

Also note, this came from a project with a tsconfig

```js
"useDefineForClassFields": false
```

+ browserslist target `ios 16` where ES2022 `@babel/plugin-transform-class-properties` is off and ES2022 `@babel/plugin-transform-class-static-block` on.
@Boshen Boshen added the 0-merge Merge with Graphite Merge Queue label Aug 6, 2025
@graphite-app graphite-app bot force-pushed the 08-06-fix_minifier_keep_classes_that_may_have_side_effects branch from e3022ab to 44b37f7 Compare August 6, 2025 14:49
@graphite-app graphite-app bot merged commit 44b37f7 into main Aug 6, 2025
29 checks passed
@graphite-app graphite-app bot deleted the 08-06-fix_minifier_keep_classes_that_may_have_side_effects branch August 6, 2025 14:55
@graphite-app graphite-app bot removed the 0-merge Merge with Graphite Merge Queue label Aug 6, 2025
Boshen added a commit to rolldown/rolldown that referenced this pull request Aug 6, 2025
Boshen added a commit to rolldown/rolldown that referenced this pull request Aug 7, 2025
github-merge-queue bot pushed a commit to rolldown/rolldown that referenced this pull request Aug 7, 2025
github-merge-queue bot pushed a commit to rolldown/rolldown that referenced this pull request Aug 7, 2025
github-merge-queue bot pushed a commit to rolldown/rolldown that referenced this pull request Aug 7, 2025
taearls pushed a commit to taearls/oxc that referenced this pull request Aug 12, 2025
…ializer (oxc-project#12848)

For the record, here's the whole process:

[TypeScript ES2022 + useDefineForClassFields = false](https://www.typescriptlang.org/play/?useDefineForClassFields=true&noUnusedLocals=true&noUnusedParameters=true&experimentalDecorators=true&emitDecoratorMetadata=true&target=9&jsx=0&module=0&stripInternal=false&isolatedModules=false&verbatimModuleSyntax=false&allowSyntheticDefaultImports=true&isolatedDeclarations=false&noCheck=false&lib=true&ts=5.9.2&filetype=ts#code/MYGwhgzhAEDC0G8BQ1oQC5nQS2NAZtALyIC+A3EqUA) transforms

(Note Oxc has the exact same transform)

```js
class C {
  static f = side_effect();
}
```

into

```js
class C {
  static {
    this.f = side_effect();
  }
}
```

then babel [@babel/plugin-transform-class-static-block](https://babel.dev/repl#?corejs=3.21&spec=true&code_lz=MYGwhgzhAEDC0G8BQ1XQgFzBglsR0GAFjhAHQBm0AvIgL4Dc0dSdQA&forceAllTransforms=true&modules=commonjs&timeTravel=true&sourceType=module&lineWrap=true&presets=react%2Ctypescript&version=7.26.1&externalPlugins=%40babel%2Fplugin-transform-class-static-block%407.27.1) transforms to

(Note Oxc has the exact same transform)

```js
class C {
  static #_ = this.f = side_effect();
}
```

and the minifier remove unused code trims it down to

```js
this.f = side_effect();
```

---

To eliminate this bug, we will temporary keep all classes that have static properties + side effect initializer.

i.e.

```js
class C {
  static #_ = this.f = side_effect();
}
```

does not get trimmed down to `this.f = side_effect()`.

---

Also note, this came from a project with a tsconfig

```js
"useDefineForClassFields": false
```

+ browserslist target `ios 16` where ES2022 `@babel/plugin-transform-class-properties` is off and ES2022 `@babel/plugin-transform-class-static-block` on.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-minifier Area - Minifier C-bug Category - Bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants