mirror of
https://github.com/oxc-project/oxc.git
synced 2026-09-14 19:36:11 +08:00
9ef028c2ad
Closes #17068. Supersedes #18095 / #18118. Adds `CodegenOptions::ascii_only` (and `codegen.asciiOnly` in `oxc_minify_napi`): escape every non-ASCII character in string literals, untagged template literals, regexp literals, directives and identifier names so the output is 7-bit clean — like esbuild `--charset=ascii` / terser `format.ascii_only`. Off by default; the default path is untouched (codegen bench and conformance unchanged). ```js // Input let café = "naïve 😀"; let re = /[–—]/u; // Output with ascii_only: true let caf\u00E9 = "na\u00EFve \u{1F600}"; let re = /[\u2013\u2014]/u; ``` Characters above U+FFFF use ES2015 code-point escapes. Regex patterns use escaped surrogate pairs instead; RegExp.prototype.source reflects the escaped spelling. Tagged template quasis, JSX names/text/attribute strings, hashbangs and preserved comments may still contain non-ASCII characters. JavaScript expressions inside tagged templates and JSX are escaped normally. Performance; with the option disabled, codegen codspeed benchmarks are withing noise (<1%). With the option on, performance is only affected for files that contain non ascii characters. --- Our use case is a large Vite/Rolldown app served through proxies that mangle non-ASCII JS (previously handled by terser's `ascii_only`); #17068 also lists deno_core snapshots and Chrome extension content scripts. AI-assisted (Claude Code); I reviewed the code, wrote the tests, and have been running this in production builds via a vendored `oxc_codegen`. --------- Co-authored-by: Samuel Attard <6634592+MarshallOfSound@users.noreply.github.com> Co-authored-by: Cameron Clark <cameron.clark@hey.com> Co-authored-by: Dunqing <dengqing0821@gmail.com>
351 lines
9.6 KiB
TypeScript
351 lines
9.6 KiB
TypeScript
/* auto-generated by NAPI-RS */
|
|
/* eslint-disable */
|
|
|
|
export interface CodegenOptions {
|
|
/**
|
|
* Remove whitespace.
|
|
*
|
|
* @default true
|
|
*/
|
|
removeWhitespace?: boolean
|
|
/**
|
|
* Escape non-ASCII characters in string literals, untagged template literals, regular
|
|
* expression literals and identifier names.
|
|
*
|
|
* Uses `\uXXXX` for characters up to U+FFFF and `\u{...}` for higher code points.
|
|
* Regular expressions use escaped UTF-16 surrogate pairs for higher code points instead;
|
|
* escaping changes the observable `RegExp.prototype.source` value.
|
|
*
|
|
* Code point escapes (`\u{...}`) require ES2015 or later; this option does not provide
|
|
* ES5-compatible output.
|
|
*
|
|
* Non-ASCII characters are left unescaped in tagged template quasis (whose raw text is
|
|
* observable), JSX names and text, JSX attribute strings, hashbangs and preserved comments.
|
|
* JavaScript expressions inside tagged templates and JSX are escaped normally.
|
|
*
|
|
* @default false
|
|
*/
|
|
asciiOnly?: boolean
|
|
/**
|
|
* How to handle legal comments (comments containing `@license`, `@preserve`, or starting with `//!`/`/*!`).
|
|
*
|
|
* * `"none"` - Do not preserve any legal comments.
|
|
* * `"inline"` - Preserve all legal comments inline.
|
|
* * `"eof"` - Move all legal comments to the end of the file.
|
|
* * `"external"` - Extract legal comments without linking.
|
|
* * `{ linked: "path/to/legal.txt" }` - Extract legal comments and add a link comment to the given path.
|
|
*
|
|
* @default "none" (when minifying)
|
|
*/
|
|
legalComments?: 'none' | 'inline' | 'eof' | 'external' | { linked: string }
|
|
}
|
|
|
|
export interface CompressOptions {
|
|
/**
|
|
* Set desired EcmaScript standard version for output.
|
|
*
|
|
* Set `esnext` to enable all target highering.
|
|
*
|
|
* Example:
|
|
*
|
|
* * `'es2015'`
|
|
* * `['es2020', 'chrome58', 'edge16', 'firefox57', 'node12', 'safari11']`
|
|
*
|
|
* @default 'esnext'
|
|
*
|
|
* @see [oxc#target](https://oxc.rs/docs/guide/usage/transformer/lowering#target)
|
|
*/
|
|
target?: string | Array<string>
|
|
/**
|
|
* Pass true to discard calls to `console.*`.
|
|
*
|
|
* @default false
|
|
*/
|
|
dropConsole?: boolean
|
|
/**
|
|
* Remove `debugger;` statements.
|
|
*
|
|
* @default true
|
|
*/
|
|
dropDebugger?: boolean
|
|
/**
|
|
* Pass `true` to drop unreferenced functions and variables.
|
|
*
|
|
* Simple direct variable assignments do not count as references unless set to `keep_assign`.
|
|
* @default true
|
|
*/
|
|
unused?: boolean | 'keep_assign'
|
|
/** Keep function / class names. */
|
|
keepNames?: CompressOptionsKeepNames
|
|
/**
|
|
* Join consecutive var, let and const statements.
|
|
*
|
|
* @default true
|
|
*/
|
|
joinVars?: boolean
|
|
/**
|
|
* Join consecutive simple statements using the comma operator.
|
|
*
|
|
* `a; b` -> `a, b`
|
|
*
|
|
* @default true
|
|
*/
|
|
sequences?: boolean
|
|
/**
|
|
* Set of label names to drop from the code.
|
|
*
|
|
* Labeled statements matching these names will be removed during minification.
|
|
*
|
|
* @default []
|
|
*/
|
|
dropLabels?: Array<string>
|
|
/** Limit the maximum number of iterations for debugging purpose. */
|
|
maxIterations?: number
|
|
/** Treeshake options. */
|
|
treeshake?: TreeShakeOptions
|
|
}
|
|
|
|
export interface CompressOptionsKeepNames {
|
|
/**
|
|
* Keep function names so that `Function.prototype.name` is preserved.
|
|
*
|
|
* This does not guarantee that the `undefined` name is preserved.
|
|
*
|
|
* @default false
|
|
*/
|
|
function: boolean
|
|
/**
|
|
* Keep class names so that `Class.prototype.name` is preserved.
|
|
*
|
|
* This does not guarantee that the `undefined` name is preserved.
|
|
*
|
|
* @default false
|
|
*/
|
|
class: boolean
|
|
}
|
|
|
|
export interface LegalCommentsLinked {
|
|
/**
|
|
* Extract legal comments and write them to the given path, with a link
|
|
* comment appended to the generated code.
|
|
*/
|
|
linked: string
|
|
}
|
|
|
|
export declare const enum LegalCommentsMode {
|
|
/** Do not preserve any legal comments. */
|
|
None = 'none',
|
|
/** Preserve all legal comments inline. */
|
|
Inline = 'inline',
|
|
/** Move all legal comments to the end of the file. */
|
|
Eof = 'eof',
|
|
/** Extract legal comments without linking. */
|
|
External = 'external',
|
|
}
|
|
|
|
export interface MangleOptions {
|
|
/**
|
|
* Pass `true` to mangle names declared in the top level scope.
|
|
*
|
|
* @default true for modules and commonjs, otherwise false
|
|
*/
|
|
toplevel?: boolean
|
|
/**
|
|
* Preserve `name` property for functions and classes.
|
|
*
|
|
* @default false
|
|
*/
|
|
keepNames?: boolean | MangleOptionsKeepNames
|
|
/**
|
|
* Names that bindings must not be renamed to, and that bindings already
|
|
* carrying them keep. Equivalent to terser's `mangle.reserved`.
|
|
*
|
|
* Pass `['exports', 'module']` when minifying prebuilt CommonJS / UMD files
|
|
* that Node consumers `import` directly, so Node's cjs-module-lexer can still
|
|
* detect the mangled module's named exports.
|
|
*
|
|
* @default []
|
|
*/
|
|
reserved?: Array<string>
|
|
/** Debug mangled names. */
|
|
debug?: boolean
|
|
}
|
|
|
|
export interface MangleOptionsKeepNames {
|
|
/**
|
|
* Preserve `name` property for functions.
|
|
*
|
|
* @default false
|
|
*/
|
|
function: boolean
|
|
/**
|
|
* Preserve `name` property for classes.
|
|
*
|
|
* @default false
|
|
*/
|
|
class: boolean
|
|
}
|
|
|
|
export interface ManglePropertiesOptions {
|
|
/**
|
|
* JavaScript `RegExp` selecting property names to mangle. The source and flags are compiled
|
|
* with Rust's regex engine. Flags `i`, `m`, `s`, and `u` are supported.
|
|
*/
|
|
include: RegExp
|
|
/** JavaScript `RegExp` excluding property names selected by `include`. */
|
|
exclude?: RegExp
|
|
/** Exact names that are neither mangled nor emitted as automatic output names. */
|
|
reserved?: Array<string>
|
|
/**
|
|
* Mangle quoted property occurrences in addition to unquoted occurrences.
|
|
*
|
|
* @default false
|
|
*/
|
|
quoted?: boolean
|
|
/**
|
|
* Generate readable `_$name$_`-style output names.
|
|
*
|
|
* @default false
|
|
*/
|
|
debug?: boolean
|
|
/**
|
|
* Stable mappings from original names to output names. `false` reserves an original name.
|
|
* Entries that do not match `include`, or that match `exclude`, remain inert but are
|
|
* preserved in the returned `mangleCache`. String targets must be `IdentifierName` values
|
|
* other than `__proto__`, `constructor`, or `prototype`. The original name `__proto__` is
|
|
* always reserved and cannot be used as a cache key.
|
|
*/
|
|
cache?: Record<string, string | false>
|
|
}
|
|
|
|
/**
|
|
* Minify asynchronously.
|
|
*
|
|
* Note: This function can be slower than `minifySync` due to the overhead of spawning a thread.
|
|
*/
|
|
export declare function minify(filename: string, sourceText: string, options?: MinifyOptions | undefined | null): Promise<MinifyResult>
|
|
|
|
export interface MinifyOptions {
|
|
/** Use when minifying an ES module. */
|
|
module?: boolean
|
|
compress?: boolean | CompressOptions
|
|
mangle?: boolean | MangleOptions
|
|
/**
|
|
* Mangle matching property names independently of identifier mangling. Properties owned by
|
|
* unminified code, imported module namespaces, globals, or host APIs must be excluded or
|
|
* reserved.
|
|
*/
|
|
mangleProps?: ManglePropertiesOptions
|
|
codegen?: boolean | CodegenOptions
|
|
sourcemap?: boolean
|
|
}
|
|
|
|
export interface MinifyResult {
|
|
code: string
|
|
map?: SourceMap
|
|
errors: Array<OxcError>
|
|
/**
|
|
* Legal comments extracted from the source code.
|
|
* Only populated when `codegen.legalComments` is `"linked"` or `"external"`.
|
|
*/
|
|
legalComments: Array<string>
|
|
/**
|
|
* Updated property-name cache sorted by original name. Present when `mangleProps` ran on a
|
|
* parse without errors.
|
|
*/
|
|
mangleCache?: Record<string, string | false>
|
|
}
|
|
|
|
/** Minify synchronously. */
|
|
export declare function minifySync(filename: string, sourceText: string, options?: MinifyOptions | undefined | null): MinifyResult
|
|
|
|
export interface TreeShakeOptions {
|
|
/**
|
|
* Whether to respect the pure annotations.
|
|
*
|
|
* Pure annotations are comments that mark an expression as pure.
|
|
* For example: @__PURE__ or #__NO_SIDE_EFFECTS__.
|
|
*
|
|
* @default true
|
|
*/
|
|
annotations?: boolean
|
|
/**
|
|
* Whether to treat this function call as pure.
|
|
*
|
|
* This function is called for normal function calls, new calls, and
|
|
* tagged template calls.
|
|
*/
|
|
manualPureFunctions?: Array<string>
|
|
/**
|
|
* Whether property read accesses have side effects.
|
|
*
|
|
* @default 'always'
|
|
*/
|
|
propertyReadSideEffects?: boolean | 'always'
|
|
/**
|
|
* Whether property write accesses (assignments to member expressions) have side effects.
|
|
*
|
|
* When false, assignments like `obj.prop = value` are considered side-effect-free
|
|
* (assuming the object and value expressions themselves are side-effect-free).
|
|
*
|
|
* @default true
|
|
*/
|
|
propertyWriteSideEffects?: boolean
|
|
/**
|
|
* Whether accessing a global variable has side effects.
|
|
*
|
|
* Accessing a non-existing global variable will throw an error.
|
|
* Global variable may be a getter that has side effects.
|
|
*
|
|
* @default true
|
|
*/
|
|
unknownGlobalSideEffects?: boolean
|
|
/**
|
|
* Whether invalid import statements have side effects.
|
|
*
|
|
* Accessing a non-existing import name will throw an error.
|
|
* Also import statements that cannot be resolved will throw an error.
|
|
*
|
|
* @default true
|
|
*/
|
|
invalidImportSideEffects?: boolean
|
|
}
|
|
|
|
export interface Comment {
|
|
type: 'Line' | 'Block'
|
|
value: string
|
|
start: number
|
|
end: number
|
|
}
|
|
|
|
export interface ErrorLabel {
|
|
message: string | null
|
|
start: number
|
|
end: number
|
|
}
|
|
|
|
export interface OxcError {
|
|
severity: Severity
|
|
message: string
|
|
labels: Array<ErrorLabel>
|
|
helpMessage: string | null
|
|
codeframe: string | null
|
|
}
|
|
|
|
export declare const enum Severity {
|
|
Error = 'Error',
|
|
Warning = 'Warning',
|
|
Advice = 'Advice',
|
|
}
|
|
|
|
export interface SourceMap {
|
|
file?: string
|
|
mappings: string
|
|
names: Array<string>
|
|
sourceRoot?: string
|
|
sources: Array<string>
|
|
sourcesContent?: Array<string>
|
|
version: number
|
|
x_google_ignoreList?: Array<number>
|
|
}
|