## Summary
close: #13067
Part of https://github.com/oxc-project/oxc/issues/19673
Depends on #20217.
Port known-globals lists from Rolldown to Oxc's side-effect detection:
- **Global identifiers** (Math, Array, console, DOM classes, etc.) are now considered side-effect-free to access via `is_known_global_identifier`, matching Rolldown's `GLOBAL_IDENT` set
- **Property reads** like `Math.PI`, `console.log`, `Object.keys` are considered side-effect-free via `is_known_global_property`
- **3-level chains** like `Object.prototype.hasOwnProperty` are supported via `is_known_global_property_deep`
## Test plan
- [x] Added tests for known global identifiers (Math, Array, Object, console, etc.)
- [x] Added tests for known global property reads (Math.PI, Object.keys, etc.)
- [x] Added tests for 3-level chains (Object.prototype.hasOwnProperty, etc.)
- [x] Existing minifier test expectations updated for improved side-effect detection
- [x] All existing tests pass
🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(napi/minify): expose `treeshake` options
## Completed:
- [x] Understand the problem: Need to expose TreeShakeOptions to JavaScript users
- [x] Explore existing code structure and TreeShakeOptions in oxc_minifier
- [x] Build the project to ensure clean state
- [x] Add TreeShakeOptions struct with all fields
- [x] Update CompressOptions to accept optional treeshake field
- [x] Implement conversion from NAPI TreeShakeOptions to oxc_minifier::TreeShakeOptions
- [x] Build and verify TypeScript definitions are generated correctly
- [x] Add tests for treeshake options
- [x] Run all tests successfully
- [x] Format code with just fmt
- [x] Address all review feedback:
- Renamed TreeShakeOptionsNapi to TreeShakeOptions
- Changed property_read_side_effects to accept boolean | 'always'
- Changed @default from true to 'always' for property_read_side_effects
- Reverted From implementation back to use reference (From<&TreeShakeOptions>)
- Changed to TryFrom to properly handle validation errors
- Added validation for propertyReadSideEffects string values
- Fixed clippy lint for inline format args
## Changes Made:
1. Added `TreeShakeOptions` struct with fields:
- `annotations`: Whether to respect pure annotations (@__PURE__, #__NO_SIDE_EFFECTS__)
- `manual_pure_functions`: List of function names to treat as pure
- `property_read_side_effects`: Whether property reads have side effects (boolean | 'always', default: 'always')
- `unknown_global_side_effects`: Whether accessing global variables has side effects
2. Updated `CompressOptions` to include optional `treeshake` field
3. Implemented `TryFrom<&TreeShakeOptions>` trait with proper error handling for invalid values
4. Added validation that rejects invalid string values for propertyReadSideEffects
5. Added tests covering treeshake functionality including error cases
6. Fixed all lint issues
All tests pass successfully!
<!-- START COPILOT CODING AGENT SUFFIX -->
<details>
<summary>Original prompt</summary>
> Add bindings for treeshake option here:
> https://github.com/oxc-project/oxc/blob/3fbb307367a31817a297dee299fec580912675db/napi/minify/src/options.rs#L90
</details>
<!-- START COPILOT CODING AGENT TIPS -->
---
💬 We'd love your input! Share your thoughts on Copilot coding agent in our [2 minute survey](https://gh.io/copilot-coding-agent-survey).
closes#13174
This should reduce sourcemap memory usage by a huge amount.
These tokens were added in esbuild for code coverage: https://github.com/evanw/esbuild/commit/c4d45e6b5766b1a1b56bf24b7dadb240de91332b
But esbuild has an optimization to not generate these tokens when `}` is not on the same line
```
if class.CloseBraceLoc.Start > class.BodyLoc.Start {
p.addSourceMapping(class.CloseBraceLoc)
}
```
We should revisit these tokens later in the future.
Just noticed that we can use a static list here. I think this has no downsides. To have better compression, we can actually count the characters, but I guess there won't be much difference normally.
Changed the mangler to reuse variable names where possible.
This will reduce the code size as shorter variable names can be used in
more places. But requires global information and limits parallelism in a
single file and requires more memory.
---------
Co-authored-by: Boshen <boshenc@gmail.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>