complexity 是决定引擎施加多少保护的唯一旋钮。预设就是它上面一个有名字的点:light 是 5,hard 是 12。light 会重命名标识符、重写语法并编码字符串,不添加结构层;从 medium 起,以及对于你直接设置的任何值,每一个词元都会被推向该目标。想要介于两者之间或超出范围的值,就直接设置 complexity——它是一个无上限的非负数。
数值升高时什么随之增加
复杂度是一份预算,而不是一张时间表。不存在“到这个数值就开启这个功能”的固定列表。高于 0 时,数值越大,引擎可用的预算就越多,并在每次构建中协商要应用哪些变换——因此相同复杂度下的两次构建形态各不相同,也没有任何单个变换能保证在某个级别出现。这种逐构建的差异正是目的所在:固定的结构为什么会成为指纹,参见 AfterPack 的工作原理。
有三点是固定的:
complexity | 保证的内容 |
|---|---|
0(minify) | 不做混淆。标识符会被重命名,代码会被压缩;下面的内容都不会运行。引擎 0.2.2 在 0 时还会重写语法。 |
> 0 | 引擎能重写的每一个字符串字面量都会经过运行时解码器——即字符串下限。 |
≥ 7(medium 及以上) | 编码后的字符串和整数以一个共享的运行时值为密钥,对象字面量会被重建成各种不同的形态。 |
其余一切——控制流重塑、不透明谓词、整数表达式解释等等——都随预算增长从中支取,而不是在某条线上开启。inflation.max 不会改变其中哪些被应用:不设置时,完全由目标决定;设置了它,膨胀会超过该值的构建就会失败。
关闭或开启某个变换
你可以关闭任何一种变换,但无法强制开启某一种。
- 关闭是可靠的。
transforms.<kind>.enabled = false在任何复杂度下都会移除该种变换。从引擎 0.2.3 起,在7及以上关闭scopeDeepen可能让文件的某一部分达不到目标,此时构建会以DIAG_TARGET_NOT_REACHED失败,并指出相应的行。 - 开启只是许可。
true允许引擎使用某种变换;是否需要它,仍由引擎在每次构建时根据复杂度和预算决定。在你提高的区域之外,light构建应用的变换种类只有字符串编码,在 Pro 上另加comparisonHardening。objectConstruction只在7(medium)及以上出现,两种 Pro 变换需要 Pro 构建。 - 在
0时,这些都不适用。minify不运行任何变换,因此所有transforms标志都没有意义。
想让某个变换更可能出现,应提高 complexity,而不是切换某个标志。
下一步
- 预设:各个有名字的级别,以及每个级别设定的体积预算。
- 配置:每一个键,包括
transforms.<kind>.enabled标志。 - AfterPack 的工作原理:为什么变换的组合每次构建都会变化。
- 指令:为单个区域设置不同的复杂度(Pro)。