Commit Graph

29 Commits

Author SHA1 Message Date
碳苯 Carbon affeb14f5a fix(minifier): mangle class private members in Node API (#26118)
## Summary

Fixes #26097.

The minify function did not work on class private fields,because their
mappings were not forwarded to codegen:

```rs
class Foo {
  #privateField = 1;

  method() {
    return this.#privateField;
  }
}
```

And this PR is to make it match what's expected:

```rs
class Foo {
  #e = 1;

  method() {
    return this.#e;
  }
}
```
2026-09-07 14:36:22 +09:00
Dunqing 241c559b83 fix(napi/minify): accept RegExp for property filters (#25827)
This follows up on #24741 and addresses API feedback received after it was merged.

### Feature

`mangleProps.include` and `mangleProps.exclude` now accept JavaScript `RegExp` values instead of strings.

The binding copies the regular expression source and flags before async minification starts, then compiles the pattern once with Rust's regex engine. Native and WASI bindings expose the same API. The core Rust minifier API is unchanged.

### Example

```js
mangleProps: {
  include: /^_/,
  exclude: /^__public/,
}
```

### Limitation

Matching uses Rust regex syntax. The `i`, `m`, `s`, and `u` flags are supported. Unsupported JavaScript syntax or flags are returned as option errors.

### AI assistance

OpenAI Codex was used for research, implementation, review, and testing. I reviewed and take responsibility for the changes.
2026-08-18 05:37:31 +00:00
Dunqing a169e4adf8 feat(napi/minify): expose property name mangling options (#24741)
The property mangler added in #24740 is not available through `oxc-minify`. This adds `mangleProps` for configuring it and `mangleCache` for reusing chosen property names.

### Feature

- `include` selects property names to mangle. `exclude` and `reserved` keep names unchanged.
- `quoted` also mangles quoted property names. `debug` produces readable output names.
- `cache` fixes a property to a chosen name. A `false` value keeps the original name.
- Property mangling works in both sync and async APIs. It is separate from identifier mangling.
- When property mangling is enabled and the call succeeds, the result includes the updated `mangleCache`.
- Invalid `mangleProps` regexes and cache entries are returned in `result.errors`.

### Design

The binding converts JavaScript values into core minifier options and results. The core minifier still chooses names and rewrites properties, so both APIs follow the same rules.

A parser error may leave an incomplete AST. In that case, property mangling is skipped and no partial cache is returned.

### Example

```js
const result = minifySync(
  "test.js",
  "let local; obj._often; obj._rare; obj._often;",
  {
    compress: false,
    mangle: false,
    mangleProps: { include: "^_" },
  },
);

result.code; // "let local;obj.e;obj.t;obj.e;"
result.mangleCache; // { _often: "e", _rare: "t" }
```

### Limitation

- `include` and `exclude` use Rust regex syntax. They match anywhere unless the pattern includes anchors.
- Do not reuse the cache on already-mangled output. A mapping is not always safe to apply twice.
- The cache only remembers recorded mappings. It cannot find unchanged names in another input or in external code. Reserve, exclude, or pin those names before the first call.
- String cache targets must be valid JavaScript `IdentifierName` values and cannot be `__proto__`, `constructor`, or `prototype`. The original name `__proto__` cannot be a cache key.

AI assistance: OpenAI Codex and Claude were used for research, implementation, adversarial review, and verification. The contributor remains responsible for reviewing, understanding, and submitting the changes under the repository AI usage policy.
2026-08-18 02:40:36 +00:00
Dunqing e7163b6720 feat(ecmascript): add known-globals to side-effect-free property reads (#20212)
## 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)
2026-03-12 09:22:57 +00:00
sapphi-red 2bf7293c69 feat(mangler)!: enable top_level by default for modules and commonjs (#18278)
I think we can enable `top_level` by default.

refs #18233
2026-02-06 12:48:44 +00:00
Boshen 523a30a016 style(all): apply oxfmt default options (#16091)
Embrace the defaults!

---------

Co-authored-by: Yuji Sugiura <y.sugiura.0316@gmail.com>
2025-11-25 15:56:24 +09:00
Boshen ea51b0b5c8 feat(napi)!: standardize function naming with sync suffixes (#15661)
closes #15576

## Summary

Standardizes function naming across all NAPI packages (parser, transform, minify) with a consistent pattern:
- Async functions: `verb` (no suffix)
- Sync functions: `verbSync` (with Sync suffix)

## Changes

### Breaking Changes

**napi/parser:**
- `parseAsync` → `parse` (async)
- `parseSync` remains unchanged (sync)

**napi/transform:**
- `transformAsync` → `transform` (async)
- `transform` → `transformSync` (sync)
- `isolatedDeclaration` → `isolatedDeclarationSync` (sync)
- Added new `isolatedDeclaration` function (async)
- `moduleRunnerTransform` → `moduleRunnerTransformSync` (sync)
- Added new `moduleRunnerTransform` function (async)

**napi/minify:**
- `minify` → `minifySync` (sync)
- Added new `minify` function (async)

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2025-11-13 12:28:23 +00:00
copilot-swe-agent 1c31cb1a08 feat(napi/minify): expose treeshake options (#15109)
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).
2025-10-30 08:46:30 +00:00
leaysgur a8e5181ab7 chore(infra): dogfooding oxfmt (#14979)
Fixes #14803

- Added `oxfmt` and `oxfmtrc.jsonc`
- Remove `dprint` plugin and useless ignore paths
- Apply `dprint` again
- Apply `oxfmt`
2025-10-28 01:16:46 +00:00
sapphi-red 9e36186e4c feat(napi/minify): expose drop_labels option (#14635)
Exposed the `drop_labels` option from JS API.
2025-10-16 06:07:18 +00:00
Boshen f10ac33979 fix(codegen): remove end sourcemaps for }, ], ) (#13180)
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.
2025-08-18 11:45:14 +00:00
Boshen 522356201b refactor(codegen): adjust some source mappings (#13084)
closes #12395
2025-08-14 09:54:29 +00:00
Boshen a286dd4a5b feat(minifier): remove unnecessary 'use strict' directive (#12642) 2025-07-31 05:07:44 +00:00
Boshen 8bae4176ff perf(codegen): remove the useless tokens generated by some expressions (#12394) 2025-07-20 03:58:15 +00:00
Boshen 1b80633434 feat(minifier): remove unused function declaration (#12318) 2025-07-16 10:29:07 +00:00
Boshen 3f33e8c8b5 feat(minifier): remove unused assignment expression (#12314)
```
var x = 1;
x = 2; // remove
```

Remove the entier thing if the binding has no read references.
2025-07-16 07:37:21 +00:00
Dunqing cd984263c2 fix(semantic): handle var hoisting in catch block with same catch parameter name (#12313)
The root cause is that the variable was hoisted to a scope that has the same name binding

```js
var a = 1;
try {
  throw 2
} catch (a) {
  var a = 3;
//    ^ Shouldn't hoist to the top scope because there is a same name variable.
}
console.log(a);
```

Ref: https://tc39.es/ecma262/#sec-variablestatements-in-catch-blocks

Note

The [Block](https://tc39.es/ecma262/#prod-Block) of a [Catch](https://tc39.es/ecma262/#prod-Catch) clause may contain var declarations that bind a name that is also bound by the [CatchParameter](https://tc39.es/ecma262/#prod-CatchParameter). At runtime, such bindings are instantiated in the VariableDeclarationEnvironment. They do not shadow the same-named bindings introduced by the [CatchParameter](https://tc39.es/ecma262/#prod-CatchParameter) and hence the [Initializer](https://tc39.es/ecma262/#prod-Initializer) for such var declarations will assign to the corresponding catch parameter rather than the var binding.
2025-07-16 06:54:38 +00:00
Boshen fb8289c5d3 feat(minifier): remove unused variable declaration (#11796)
closes #10033
2025-07-16 13:31:44 +08:00
Boshen 395aa5e9ce feat(napi/minify): return parse errors (#12112)
closes #12101
2025-07-07 07:11:02 +00:00
Boshen bd953fce3a fix(napi/minify): need to remove all comments (#10785)
fixes #10784
2025-05-04 06:30:44 +00:00
Boshen a6c9b0949c docs(napi/minifier): improve documentation (#9736) 2025-03-13 06:28:23 +00:00
Boshen d129055dc6 test(napi): add tests for worker threads (#9408)
There are user code which may crash under some random circumstances
that we don't understand. Prevent these crashes with a test.
2025-02-27 07:19:11 +00:00
sapphi-red 86b6219d26 feat(mangler): use characters in the order of their likely frequency (#8771)
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.
2025-01-29 02:20:44 +00:00
翠 / green 6589c3bbb3 feat(mangler): reuse variable names (#8562)
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>
2025-01-25 14:00:24 +08:00
Boshen 9ec4e24eb7 test(napi/minify): fix more broken tests 2025-01-16 16:09:23 +08:00
Boshen 0acbef356a test(napi/minify): fix matching of arrays 2025-01-16 15:34:20 +08:00
Boshen 855c8395cf fix(codegen): shorthand assignment target identifier consider mangled names (#8536) 2025-01-16 07:26:07 +00:00
Boshen c63c8b924d test(napi/minify): add runtime test (#8501) 2025-01-15 21:13:00 +08:00
Boshen 4ad695dcfb feat(napi/minify): implement napi (#8478) 2025-01-14 08:55:55 +00:00