混淆预设

从 minify 到 extreme 的五个保护级别,每个级别设定的复杂度目标,以及零配置默认值(light)已经保证的内容。

预设是一组有名称的变换,具有已知的体积和运行时代价。更重的预设施加更多变换,但这并不是经过测量的保护提升。一个名称设定一个复杂度目标;输出体积由该目标决定。显式设置 complexity 会覆盖该目标,而直接设置的值总是作用于每一个 token,即使在 light 下也是如此。

The five obfuscation presets ranked by complexity target, with light marked as the defaultextremetarget 25hardtarget 12mediumtarget 7lighttarget 5DEFAULTminifytarget 0Zero config gives you light: string literals encoded. Step up per project.

阶梯

预设complexity典型 gzip 后体积字符串下限适用场景
minify01.09x 至 1.17x关闭不做混淆。标识符会被重命名,代码会被压缩;字符串字面量保持可读。
light51.29x 至 1.60x开启**默认。**在 minify 的基础上加入字符串编码并重写语法,不添加结构层。适合大多数项目的基线。
medium76.04x 至 8.33x开启希望明显更难跟读的生产代码。
hard126.62x 至 9.23x开启关键代码:定价、功能门控、许可证校验、客户端业务逻辑。
extreme258.25x 至 11.19x开启实际应用的最高复杂度。将它用于单个文件或区域,而不是整个 bundle。

以上是针对同一份已压缩文件的 gzip 后输出体积,在五个真实的、已压缩的生产 bundle 上用 AfterPack 0.2.6 于 2026-10-16 测得;方法见性能。

任何正数目标都会开启字符串下限。

默认为 light

不带 --preset 运行 npx afterpack@latest dist/,或者安装一个插件而不做任何配置,得到的就是 light。

$ npx afterpack@latest dist/
npx afterpack@latest dist/ --preset=hard    # step up

命令行参数用 = 连接取值。用空格分隔的取值会被当作未知参数而拒绝。

light 是零配置的下限。它能重写的每一个字符串字面量都会经过运行时解码器。它会重命名标识符并重写语法,且不添加结构层。从引擎 0.2.3 起,minify 和 light 不再把循环改写成回调辅助函数,从而消除了这些辅助函数在热点循环中造成的 2-5 倍减速。在 light 下,属性名和全局名仍然经由编码常量访问,这在非常热的代码中会有一定开销。有些字符串在任何预设下都保持可读:指令序言、typeof 的比较对象、运行时需要的属性名,以及导出名。Protection Map 会列出它们,引擎也会在每次构建时报告其数量和字节总数。把预设提高到 medium 或以上,会在每一个词元上增加结构性工作:膨胀、控制流重塑,以及以一个共享的运行时值为密钥的字符串和整数。它不会改变字符串的可读性,因为可读性已经处于下限。

minify 是唯一关闭这一下限的级别。从引擎 0.2.3 起,它只重命名标识符并压缩代码,不应用任何混淆。引擎 0.2.2 在 minify 下还会重写语法。

体积预算

每份输出都带有引擎固定的运行时开销(解码器和整数表达式解释器),因此几百字节的小文件产出会比上表的比例还要大得多。请在真实的 bundle 上读取比值,而不是小文件。

inflation.max 默认未设置,因此复杂度目标独自决定输出体积。只有当你有一个宁可失败也不愿超出的真实体积预算时,才自己设置它。触及显式设置的值是一个错误:DIAG_SIZE_CAP_REACHED,没有输出,CLI 以退出码 3退出,插件则让构建失败。从引擎 0.2.3 起,绝不会写出保护不足的输出来替代:最终生成的文件会按上限检查,并且字符串编码总是先完成。在引擎 0.2.2 中,过紧的上限可能让字符串编码提前停止,使部分字符串保持可读。

直接设置目标

complexity 是一个无上限的非负数。--complexity=200 是 Free 层级下有效的覆盖值,远超 extreme 所设定的数值。

npx afterpack@latest dist/ --preset=hard --complexity=40

这相当于把 hard 的复杂度目标覆盖为 40;预设的其他设置都不变。向 --complexity 传入预设名称是一个错误。

将预设应用到单个区域

--preset 对整个 bundle 统一生效;这是 Free 功能。把更重的预设集中到某个函数或文件上是 Pro 功能,通过源代码指令实现:

/* @afterpack preset=extreme */
function pricingEngine(plan, region) {
  return resolve(plan, region);
}
/* @afterpack end */

指令只能写成块注释,由插件从你的源代码中读取。语法和层级规则参见指令。

下一步