mirror of
https://github.com/aphrody-labs/oxc.git
synced 2026-10-14 22:29:17 +00:00
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.