# AfterPack 文档

一个构建后步骤，对打包工具产出的 JavaScript 进行混淆。一个开发依赖、一行配置；生产输出经过混淆，且每次构建都不同，开发环境保持不变。

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

> 别再交付你的源代码。你部署的每个 bundle 就是你的源代码：如今编码智能体几分钟内就能读懂、解释并改写压缩后的 JavaScript，所以“压缩过”只意味着“用更小的字号公开发布”。AfterPack 就是补上这个缺口的构建后步骤。一个开发依赖、一行配置，你的生产输出在交付时名称已被重命名、字符串已被编码，任何读者，无论是人还是模型，都无法用 grep 找到你的逻辑，也无法原样照搬。每次构建的形态都不同，所以针对某次构建的模式编写的工具，到下一次构建就会失效。它在你的打包工具之后运行，从不改动你的源代码，还能交给你一份 Protection Map，准确列出改动了什么。它不会把客户端的秘密变成服务端的秘密：运行你代码的人仍然能读到它用到的值。

## 适合使用的情况
- 浏览器收到的逻辑值得别人花钱去复制或绕过：许可证检查、定价规则、反作弊、付费墙、内嵌的 SDK。
- 客户或安全问卷询问你交付的 JavaScript 是否可读。
- 你希望有一个构建后步骤，完全不影响开发环境。
- 你从 Cloudflare Worker 提供 JavaScript，并希望它在每个轮换窗口改变形态。

## 可以不用的情况
- 有价值的逻辑都已在服务端运行，客户端只是一层很薄的视图。
- 代码是开源的，或本来就是给人读的。
- 你需要一个秘密在浏览器里保持秘密：没有任何混淆器能做到，AfterPack 也会明确说明这一点。

## 全部内容，一个文件
- [完整文档合集（英文）](https://www.afterpack.dev/llms-full.txt): 下列所有页面合并为一个文件。
- [配置的 JSON 版本](https://www.afterpack.dev/docs-config.json): 配置注册表，机器可读。
- [路线图](https://www.afterpack.dev/roadmap.md): 已发布的内容和接下来的计划。

## 入门
- [概览](https://www.afterpack.dev/docs.md)
- [快速上手](https://www.afterpack.dev/zh/docs/quickstart.md): 选择你的框架，安装一个开发依赖，执行构建，然后打开 Protection Map。
- [最佳实践](https://www.afterpack.dev/zh/docs/best-practices.md): 默认发布经过混淆的 JavaScript,用指令标记真正重要的区域,并持续轮换构建,让攻击者始终追不上。
- [AfterPack 的工作原理](https://www.afterpack.dev/zh/docs/concepts.md): 标准（Free）输出会对你的代码做什么、它如何抵抗还原，以及攻击者实际上能恢复出什么。

## 指南
- [构建与 CI](https://www.afterpack.dev/zh/docs/builds.md): AfterPack 在你的流水线中所处的位置：仅用于生产环境、构建一次并将同一产物推广到各阶段，附带一份 CI 配方，以及关于种子、产物、source map 和云端不可用时的规则。
- [Protection Map](https://www.afterpack.dev/zh/docs/protection-map.md): 展示 AfterPack 对你的代码做了什么的 HTML 报告：每个词元都按它经历了多少变换着色。

## 使用场景
- [付费墙检查](https://www.afterpack.dev/zh/docs/use-cases/paywall-checks.md): 打包产物中的付费墙判断是一个返回布尔值的具名函数，翻转它只需一行补丁。混淆与逐构建变化的种子如何改变查找它和让补丁保持有效这两件事。
- [定价与权限逻辑](https://www.afterpack.dev/zh/docs/use-cases/pricing-logic.md): 客户端 JavaScript 中的套餐限制、配额阈值和功能开关规则，读起来就是一份商业模式的规格说明。如何让它们不可读，以及哪些内容无论如何仍然可以被观察到。
- [随包发布的 API 密钥](https://www.afterpack.dev/zh/docs/use-cases/shipped-api-keys.md): 限制它、代理它、轮换它，然后再混淆剩下的部分。在打包产物中编码一个凭证究竟能带来什么，界限又在哪里。
- [意外泄露的密钥](https://www.afterpack.dev/zh/docs/use-cases/accidental-secrets.md): 一个凭据进入了已部署的 bundle。如何查清你的线上站点此刻暴露了什么、下一次构建会给这个值带来什么变化，以及为什么轮换才是了结此事的那一步。
- [补丁工具](https://www.afterpack.dev/zh/docs/use-cases/patching-tools.md): 用户脚本、Tampermonkey 补丁或扩展程序，都必须锚定在你 JavaScript 中的某个名称、某个字符串或某种可识别的形态上。结构性混淆和每次构建的新形态会对这些锚点产生什么影响。
- [未发布的功能](https://www.afterpack.dev/zh/docs/use-cases/unreleased-features.md): 特性开关名称、路由字符串和未发布的界面文案，在你宣布任何事情之前就已经发给了每一位访客，而人们会在多次发布之间做打包产物的差异对比。什么该剥离、什么该保护、什么该彻底排除在构建之外。
- [安全扫描器](https://www.afterpack.dev/zh/docs/use-cases/security-scanners.md): 形似密钥的模式、指回你源码的 sourceMappingURL、库指纹，以及“明文或已压缩”的标签。自动化阅读者会检查什么，以及混淆后的构建会让报告发生哪些变化。
- [Electron 许可证逻辑](https://www.afterpack.dev/zh/docs/use-cases/electron-license-logic.md): app.asar 一条命令就能解包，而本地的许可证或试用期校验通常只是一次比较。如何混淆 main、preload 和 renderer，让破解撑不过你的下一次发布。
- [浏览器扩展](https://www.afterpack.dev/zh/docs/use-cases/browser-extensions.md): 已发布的扩展是一个任何人都能解包阅读的 zip。混淆后台脚本和内容脚本会改变什么，以及发布前需要确认的商店政策。

## 框架
- [框架](https://www.afterpack.dev/zh/docs/frameworks.md): 针对你的技术栈应安装哪个包、它在何处接入，以及它会写出哪些文件。
  - [Angular](https://www.afterpack.dev/zh/docs/frameworks/angular.md): Angular v17+ 的混淆是对 dist/<app>/browser 的一次构建后处理:可以通过 CLI,也可以通过 @afterpack/angular 辅助工具。
  - [Astro](https://www.afterpack.dev/zh/docs/frameworks/astro.md): @afterpack/astro 是一个很薄的集成，把 @afterpack/vite 接入 Astro 自己的 Vite 流水线。
  - [Electron](https://www.afterpack.dev/zh/docs/frameworks/electron.md): @afterpack/electron 用一次调用、一个种子接入 main、preload 和 renderer，并在 electron-vite 的 bytecodePlugin 和缺乏防护的备份把你的源代码发布出去之前拒绝它们。
  - [esbuild](https://www.afterpack.dev/zh/docs/frameworks/esbuild.md): @afterpack/esbuild 挂接 build.onEnd，就地混淆已写出的输出。
  - [Next.js](https://www.afterpack.dev/zh/docs/frameworks/nextjs.md): @afterpack/next 在 next build 内部混淆客户端 JavaScript,支持 Turbopack 或 webpack、SSR 或静态导出。
  - [Nuxt](https://www.afterpack.dev/zh/docs/frameworks/nuxt.md): @afterpack/nuxt 是一个 Nuxt 3 模块，在 Nuxt 的 Vite 配置上注册 @afterpack/vite。
  - [Parcel](https://www.afterpack.dev/zh/docs/frameworks/parcel.md): @afterpack/parcel-optimizer 作为 Parcel 2 Optimizer,在内存中混淆每个打包产物,并在可能导致分块在生产环境 404 时使构建失败,而不是继续发布。
  - [Plain JS](https://www.afterpack.dev/zh/docs/frameworks/plain.md): 把 npx afterpack@latest 指向任意一个已生成 JavaScript 的目录。不需要打包工具,不需要插件,也不需要配置文件。
  - [Remix](https://www.afterpack.dev/zh/docs/frameworks/remix.md): 没有 @afterpack/remix 这个包。Remix 通过 Vite 构建，因此使用 @afterpack/vite，或者对构建输出运行 CLI。
  - [Rollup](https://www.afterpack.dev/zh/docs/frameworks/rollup.md): @afterpack/rollup 从你的源代码中读取 Pro 版 @afterpack 指令，并在 Rollup 写入输出之前，在 generateBundle 中运行引擎。
  - [Svelte](https://www.afterpack.dev/zh/docs/frameworks/svelte.md): @afterpack/svelte 为 Svelte 项目包装了 @afterpack/vite：在 vite.config.ts 中加一行插件。
  - [SvelteKit](https://www.afterpack.dev/zh/docs/frameworks/sveltekit.md): @afterpack/sveltekit：在 vite.config.ts 中 sveltekit() 之后加一行插件。
  - [Vite](https://www.afterpack.dev/zh/docs/frameworks/vite.md): @afterpack/vite 在 generateBundle 中混淆你的构建，早于 Vite 写出文件；它是其他所有 Vite 系包所封装的参考集成。
  - [Vue](https://www.afterpack.dev/zh/docs/frameworks/vue.md): @afterpack/vue 为 Vue 3 项目包装了 @afterpack/vite：在 vite.config.ts 中加一行插件。
  - [Webpack](https://www.afterpack.dev/zh/docs/frameworks/webpack.md): @afterpack/webpack 挂钩 compilation.hooks.processAssets，在 webpack 写入资产之前对其进行混淆。

## CLI
- [CLI](https://www.afterpack.dev/zh/docs/cli.md): 调用 npx afterpack@latest：可选的路径参数、作为标志使用的每个配置键、verify、restore 与 audit 子命令，以及完整的退出码约定。
- [审计](https://www.afterpack.dev/zh/docs/audit.md): 扫描一个线上 URL，检查公开的 source map、可读代码和泄露的凭据，并给出 100 分制的分数。与公开安全扫描器同款的扫描器，直接跑在你的终端里。

## 配置
- [配置](https://www.afterpack.dev/zh/docs/config.md): 每一个选项、在哪里设置，以及它的作用。
- [预设](https://www.afterpack.dev/zh/docs/presets.md): 从 minify 到 extreme 的五个保护级别，每个级别设定的复杂度目标，以及零配置默认值（light）已经保证的内容。
- [复杂度](https://www.afterpack.dev/zh/docs/complexity.md): 每个预设背后的那一个旋钮：数值升高时什么随之增加、在 medium 处切换的那个阈值，以及哪些变换可以通过配置关闭却无法强制开启。
- [指令](https://www.afterpack.dev/zh/docs/directives.md): 写在源码中的注释，用于改变 AfterPack 对其所标记代码的保护。

## 安全
- [威胁模型](https://www.afterpack.dev/zh/docs/threat-model.md): AfterPack 的安全评审材料：它防护的资产、每类攻击者能还原什么、秘密如何保住、当前范围止于何处，以及与它并用的控制措施。
- [还原类](https://www.afterpack.dev/zh/docs/reversal-classes.md): AfterPack 的各项变换所属的静态攻击者类别，以及恢复每一类能让攻击者得到什么。
- [隐私](https://www.afterpack.dev/zh/docs/privacy.md): 本地构建不会发送任何内容。云端构建在内存中完成混淆，不保留任何东西，除了你要求存储的 Protection Map，这项功能可以关闭。遥测默认开启，仅在构建报告错误级别诊断时上报，干净的构建从不上报，并可通过一个环境变量关闭。

## 云端与 Pro
- [Pro](https://www.afterpack.dev/zh/docs/pro.md): Free 对整个 bundle 进行统一保护。Pro 让你只在真正重要的地方施加最强保护：用指令作用于某一个函数或文件。它还会记录每一次构建。
- [云端 API](https://www.afterpack.dev/zh/docs/cloud-api.md): api.afterpack.dev 的通信契约：认证、批量混淆端点、限制、速率限制、构建时间预算，以及客户端必须处理的诊断代码。
- [部署模式](https://www.afterpack.dev/zh/docs/deployment-modes.md): 运行引擎的两种方式：在你自己的机器上本地运行，或者凭 Pro 密钥在 AfterPack 的云端运行。
- [Cloudflare Workers](https://www.afterpack.dev/zh/docs/workers.md): 用 @afterpack/wasm 在你自己的 Cloudflare Worker 中运行 AfterPack，传入 Pro 密钥即可在 AfterPack 云端构建，并按轮换窗口缓存每个结果。

## 控制台
- [控制台](https://www.afterpack.dev/zh/docs/dashboard.md): AfterPack 控制台展示什么内容、如何组织，以及哪些构建会出现在其中。
  - [工作区与项目](https://www.afterpack.dev/zh/docs/dashboard/workspaces.md): 控制台中其他一切都依附的两个对象：工作区中谁能做什么、项目如何把构建和密钥归在一起，以及各个设置页面能更改什么。
  - [构建](https://www.afterpack.dev/zh/docs/dashboard/builds.md): 每一次 Pro Cloud 构建的逐构建记录：覆盖率、膨胀率、复杂度、构建耗时、花费、诊断信息，以及 Protection Map。
  - [API 密钥](https://www.afterpack.dev/zh/docs/dashboard/api-keys.md): 创建、限定范围、使用和撤销将本地构建变为 Pro Cloud 构建的密钥。
  - [用量与账单](https://www.afterpack.dev/zh/docs/dashboard/usage.md): 如何读懂用量表、一次构建依次扣减的三个额度池、套餐卡片上的状态行，以及账单页面可以更改哪些内容。

## 套餐与账单
- [层级](https://www.afterpack.dev/zh/docs/tiers.md): Free 运行完整流程：复杂度没有上限，每个预设都可用。各层级之间的区别在于你能多精准地施加保护，以及每月能获得多少 MB 的 Pro 构建。
- [账户](https://www.afterpack.dev/zh/docs/accounts.md): AfterPack 账户是做什么用的、你的个人账户页面上有什么，以及工作区、密钥、用量和账单相关文档在哪里。
- [SLA、SLO 与支持](https://www.afterpack.dev/zh/docs/sla.md): 对于 Pro 云端 API，目标值与合同保证有何区别，事故如何处理，以及各层级对应哪个支持渠道。
- [Enterprise](https://www.afterpack.dev/zh/docs/enterprise.md): 定制合同：优先获得定制开发、在你自己云上私有部署引擎、联合安全评审，以及两种适用于不能离开你基础设施的源码的部署形态。

## 参考
- [同类对比](https://www.afterpack.dev/zh/docs/comparison.md): AfterPack 与 javascript-obfuscator、js-confuser、JScrambler、JSDefender 和 ByteHide 在构建耗时、输出体积以及输出是否仍能运行方面的对比，在同一套测试框架上测得。
- [性能](https://www.afterpack.dev/zh/docs/performance.md): AfterPack 对构建和页面的代价：在 185 KB bundle 上实测的混淆耗时、wasm 构建的耗时与下载体积、每个预设的输出体积、页面启动时间和运行时代价、受保护代码读取宿主全局对象的开销，以及新种子对缓存的影响。
- [语义契约](https://www.afterpack.dev/zh/docs/semantic-contract.md): AfterPack 的输出保留了你的程序的哪些行为，每个引擎版本如何用真实代码检验，以及简短的有意差异清单。
- [诊断](https://www.afterpack.dev/zh/docs/diagnostics.md): AfterPack 发出的每一个 DIAG_* 代码、触发它的原因、如何解决，以及构建返回的退出代码。
- [术语表](https://www.afterpack.dev/zh/docs/glossary.md): AfterPack 文档中的术语：多态性、非物化、还原类等，每个只定义一次。
- [Status API](https://www.afterpack.dev/zh/docs/status-api.md): GET /v1/status：每个 AfterPack 服务当前状态及最近 90 天每日可用率的公开汇总，也是 status.afterpack.dev 背后的数据。

## 帮助
- [常见问题](https://www.afterpack.dev/zh/docs/faq.md): 关于 AfterPack 最常被问到的问题，每个都用几段简短的文字作答。
