| | |
| | | /** @typedef {import("../Compiler")} Compiler */ |
| | | /** @typedef {import("../ExportsInfo")} ExportsInfo */ |
| | | /** @typedef {import("../ExportsInfo").ExportInfo} ExportInfo */ |
| | | /** @typedef {import("../util/concatenate").UsedNames} UsedNames */ |
| | | |
| | | /** |
| | | * Defines the comparator type used by this module. |
| | | * @template T |
| | | * @typedef {import("../util/comparators").Comparator<T>} Comparator |
| | | */ |
| | | |
| | | /** |
| | | * Checks whether it can mangle. |
| | | * @param {ExportsInfo} exportsInfo exports info |
| | | * @returns {boolean} mangle is possible |
| | | */ |
| | |
| | | }; |
| | | |
| | | // Sort by name |
| | | /** @type {Comparator<ExportInfo>} */ |
| | | const comparator = compareSelect((e) => e.name, compareStringsNumeric); |
| | | /** |
| | | * Mangle exports info. |
| | | * @param {boolean} deterministic use deterministic names |
| | | * @param {ExportsInfo} exportsInfo exports info |
| | | * @param {boolean | undefined} isNamespace is namespace object |
| | |
| | | */ |
| | | const mangleExportsInfo = (deterministic, exportsInfo, isNamespace) => { |
| | | if (!canMangle(exportsInfo)) return; |
| | | /** @type {UsedNames} */ |
| | | const usedNames = new Set(); |
| | | /** @type {ExportInfo[]} */ |
| | | const mangleableExports = []; |
| | |
| | | // Can the export be mangled? |
| | | exportInfo.canMangle !== true || |
| | | // Never rename 1 char exports |
| | | (name.length === 1 && /^[a-zA-Z0-9_$]/.test(name)) || |
| | | (name.length === 1 && /^[a-z0-9_$]/i.test(name)) || |
| | | // Don't rename 2 char exports in deterministic mode |
| | | (deterministic && |
| | | name.length === 2 && |
| | | /^[a-zA-Z_$][a-zA-Z0-9_$]|^[1-9][0-9]/.test(name)) || |
| | | /^[a-z_$][a-z0-9_$]|^[1-9][0-9]/i.test(name)) || |
| | | // Don't rename exports that are not provided |
| | | (avoidMangleNonProvided && exportInfo.provided !== true) |
| | | ) { |
| | |
| | | usedNames.size |
| | | ); |
| | | } else { |
| | | /** @type {ExportInfo[]} */ |
| | | const usedExports = []; |
| | | /** @type {ExportInfo[]} */ |
| | | const unusedExports = []; |
| | | for (const exportInfo of mangleableExports) { |
| | | if (exportInfo.getUsed(undefined) === UsageState.Unused) { |
| | |
| | | let i = 0; |
| | | for (const list of [usedExports, unusedExports]) { |
| | | for (const exportInfo of list) { |
| | | /** @type {string} */ |
| | | let name; |
| | | do { |
| | | name = numberToIdentifier(i++); |
| | |
| | | |
| | | class MangleExportsPlugin { |
| | | /** |
| | | * Creates an instance of MangleExportsPlugin. |
| | | * @param {boolean} deterministic use deterministic names |
| | | */ |
| | | constructor(deterministic) { |
| | | /** @type {boolean} */ |
| | | this._deterministic = deterministic; |
| | | } |
| | | |
| | | /** |
| | | * Apply the plugin |
| | | * Applies the plugin by registering its hooks on the compiler. |
| | | * @param {Compiler} compiler the compiler instance |
| | | * @returns {void} |
| | | */ |