# 复杂度

每个预设背后的那一个旋钮：数值升高时什么随之增加、在 medium 处切换的那个阈值，以及哪些变换可以通过配置关闭却无法强制开启。

Source: https://www.afterpack.dev/zh/docs/complexity

`complexity` 是决定引擎施加多少保护的唯一旋钮。[预设](https://www.afterpack.dev/zh/docs/presets)就是它上面一个有名字的点：`light` 是 `5`，`hard` 是 `12`。`light` 会重命名标识符、重写语法并编码字符串，不添加结构层；从 `medium` 起，以及对于你直接设置的任何值，每一个词元都会被推向该目标。想要介于两者之间或超出范围的值，就直接设置 [`complexity`](https://www.afterpack.dev/zh/docs/config#complexity)——它是一个无上限的非负数。

## 数值升高时什么随之增加

复杂度是一份预算，而不是一张时间表。不存在“到这个数值就开启这个功能”的固定列表。高于 `0` 时，数值越大，引擎可用的预算就越多，并在每次构建中协商要应用哪些变换——因此相同复杂度下的两次构建形态各不相同，也没有任何单个变换能保证在某个级别出现。这种逐构建的差异正是目的所在：固定的结构为什么会成为指纹，参见 [AfterPack 的工作原理](https://www.afterpack.dev/zh/docs/concepts)。

有三点是固定的：

| `complexity` | 保证的内容 |
|---|---|
| `0`（`minify`） | 不做混淆。标识符会被重命名，代码会被压缩；下面的内容都不会运行。引擎 0.2.2 在 `0` 时还会重写语法。 |
| `> 0` | 引擎能重写的每一个字符串字面量都会经过运行时解码器——即[字符串下限](https://www.afterpack.dev/zh/docs/presets#the-default-is-light)。 |
| `≥ 7`（`medium` 及以上） | 编码后的字符串和整数以一个共享的运行时值为密钥，对象字面量会被重建成各种不同的形态。 |

其余一切——控制流重塑、不透明谓词、整数表达式解释等等——都随预算增长从中支取，而不是在某条线上开启。[`inflation.max`](https://www.afterpack.dev/zh/docs/config#inflation-max) 不会改变其中哪些被应用：不设置时，完全由目标决定；设置了它，膨胀会超过该值的构建就会失败。

## 关闭或开启某个变换

你可以关闭任何一种变换，但无法强制开启某一种。

- **关闭是可靠的。**[`transforms.<kind>.enabled = false`](https://www.afterpack.dev/zh/docs/config) 在任何复杂度下都会移除该种变换。从引擎 0.2.3 起，在 `7` 及以上关闭 `scopeDeepen` 可能让文件的某一部分达不到目标，此时构建会以 [`DIAG_TARGET_NOT_REACHED`](https://www.afterpack.dev/zh/docs/diagnostics#complete-reference) 失败，并指出相应的行。
- **开启只是许可。**`true` 允许引擎使用某种变换；是否需要它，仍由引擎在每次构建时根据复杂度和预算决定。在你提高的区域之外，`light` 构建应用的变换种类只有字符串编码，在 Pro 上另加 `comparisonHardening`。`objectConstruction` 只在 `7`（`medium`）及以上出现，两种 Pro 变换需要 [Pro](https://www.afterpack.dev/zh/docs/pro) 构建。
- **在 `0` 时，这些都不适用。**`minify` 不运行任何变换，因此所有 `transforms` 标志都没有意义。

想让某个变换更可能出现，应提高 `complexity`，而不是切换某个标志。

## 下一步

- [预设](https://www.afterpack.dev/zh/docs/presets)：各个有名字的级别，以及每个级别设定的体积预算。
- [配置](https://www.afterpack.dev/zh/docs/config)：每一个键，包括 `transforms.<kind>.enabled` 标志。
- [AfterPack 的工作原理](https://www.afterpack.dev/zh/docs/concepts)：为什么变换的组合每次构建都会变化。
- [指令](https://www.afterpack.dev/zh/docs/directives)：为单个区域设置不同的复杂度（Pro）。
