Files
Dunqing 2f5cdb1231 feat(minifier): add property name mangling (#24740)
Oxc can shorten variable names and private class names, but it cannot shorten property names such as `obj._field`. This change adds optional property mangling. It replaces #23772 and gives bundlers a way to use the same property names across several files.

### Feature

- `include` selects names to mangle. `exclude` and `reserved` keep names unchanged.
- The cache can give a property a fixed output name or keep it unchanged.
- The mangler supports member access, object and class keys, destructuring, optional chains, the left side of `in`, and JSX property names.
- `mangle_quoted` also handles strings and template literals used directly as property keys. `/* @__KEY__ */` and `/* #__KEY__ */` can mark one other string or template literal as a property key.
- Short names are assigned in a stable order. More common properties get shorter names. Existing and reserved names are avoided.
- Bundlers can collect names from several programs, create one shared map, and apply it to every program.
- Numeric keys, `__proto__`, `constructor`, `prototype`, TypeScript-only keys, and private names are never changed by this pass.

### Design

Property names are part of JavaScript syntax, not local scope. For this reason, the code lives in `oxc_minifier`. It only reuses the short-name generator from `oxc_mangler`.

For one program, the order is:

```text
collect names → assign names → rewrite once → compress → mangle variables and private names
```

Property names are rewritten before compression because compression can remove information about quotes and comments.

For several programs, a bundler collects names from each program, merges the results, assigns one shared map, and rewrites each program once. Collection can run in parallel. All programs must use the same options.

The shared map keeps property names consistent inside one build. The cache has a different job: it keeps fixed names and reservations across separate minify calls.

### Example

With `include: "^_"` and `mangle_quoted: true`:

```js
obj[`_field`] = 1;
obj._field = 2;
```

becomes:

```js
obj[`e`] = 1;
obj.e = 2;
```

### Limitation

- Property mangling is unsafe when other code still uses the old property name. Public APIs and names shared with external code, host APIs, imported namespace objects, or separate builds must be excluded or reserved.
- Quote handling is per use. Without `mangle_quoted`, `obj._field` may change while `obj["_field"]` does not.
- The mangler cannot find names built at runtime or stored in arbitrary strings. Code that uses `eval`, `Function`, or `with` must reserve any affected names.
- Compression may create a matching property after this pass has finished. For example, `'f' + 'oo_'` may later become `foo_` and will not be mangled.
- TypeScript enum reverse mappings are not supported because the transform creates quoted strings.
- Multi-program support is a caller API. The caller must collect every program that shares mangled properties before assigning names.

The public `oxc-minify` API is stacked in #24741. The downstream multi-chunk integration is shown in rolldown/rolldown#10374.

Supersedes #23772.

AI assistance: OpenAI Codex and Claude were used for research, implementation, review, and testing. The contributor is responsible for reviewing and understanding the changes before submission.
2026-08-17 07:50:51 +00:00
..

Oxc Mangler

Variable name mangling for JavaScript minification.

Overview

This crate provides variable name mangling capabilities for JavaScript minification. It shortens variable names to reduce bundle size while preserving program semantics and ensuring gzip-friendly output.

Key Features

  • Intelligent mangling: Shortens variable names while avoiding conflicts
  • Scope-aware: Respects JavaScript scoping rules
  • Gzip optimization: Generates names that compress well
  • Configurable: Options to preserve specific names or patterns
  • Base54 encoding: Efficient character usage for maximum compression

Architecture

Mangling Strategy

  1. Symbol Analysis: Identify all variables and their scopes
  2. Frequency Analysis: Count usage to optimize for common variables
  3. Name Generation: Generate short names using base54 encoding
  4. Conflict Resolution: Ensure no naming conflicts across scopes
  5. Integration: Update symbol table with new names

Base54 Encoding

Uses a character set optimized for JavaScript identifiers:

  • First character: a-zA-Z_$ (54 options)
  • Subsequent characters: a-zA-Z0-9_$ (64 options)
  • Generates shortest possible names: a, b, ..., aa, ab, etc.

Gzip Optimization

The mangling algorithm considers:

  • Character frequency: Prefer characters that compress well
  • Repetition patterns: Generate names that create gzip-friendly patterns
  • Context awareness: Consider surrounding code when choosing names

Integration with Minifier

The mangler works as part of the broader minification pipeline:

  1. Parse: Build AST from source code
  2. Analyze: Perform semantic analysis
  3. Mangle: Shorten variable names
  4. Transform: Apply other minification transforms
  5. Generate: Output minified code

This approach ensures maximum size reduction while maintaining correctness.