AfterPack 博客
announcementjavascript obfuscationsecurityAI

发布 AfterPack:一款面向 Web 的免费 JavaScript 混淆器

由 Nikita Savchenko16 分钟阅读

今天,我们要发布三样东西:

  • AfterPack,一款面向 AI 时代的现代 JavaScript 混淆器。它把你的生产构建每次都变成一个不同的程序:每次构建都是新的样子,在 Cloudflare Worker 里,每次请求也是新的样子。
  • 全新升级的网站扫描器,能找出任何网站代码里可读的部分:公开的 source map、可读的逻辑和泄露的凭据。
  • 在线 playground,直接在浏览器里,用你自己的代码试试 AfterPack。

AfterPack(afterpack.dev)是一款 JavaScript 混淆器,支持任何框架。CLI 和插件是开源的,本地引擎免费,Pro 云端构建每月 49 美元起。构建之后运行 npx afterpack@latest 即可开始,或者让你的编码 Agent 帮你添加它。

认识一下 AfterPack:一个免费的构建工具,它让你发布出去的代码对扫描器和人都读不懂,也让 AI 追不上。每次构建都是完全不同的代码,所以针对某一个版本写的补丁脚本——外挂、用户脚本、绕过手段——都套不进下一个版本。一个针对你代码写出来的工具,本就该在你下一个版本失效;现在,在你自己的 Cloudflare Worker 里,它甚至能在下一次请求就失效。

AI 都能读懂 JavaScript 了,为什么还要混淆?

因为 AI 能读懂的东西,它也能重写、重新打包。把编码 Agent 指向你的 bundle,几分钟后,有人手里就拿到了你的定价规则、付费墙校验或反机器人逻辑的干净、可编辑源码,还附带一个能打补丁或绕过它们的脚本。这以前是专家才干得了的活;现在只是一句提示词。而且只要你的代码结构不变,这个补丁就能一直用下去。压缩从来没有把这些代码藏起来:所谓的 Claude Code「泄露」,其实就是一个自发布起就躺在 npm 上、本来就可读的 bundle。压缩后的 bundle 仍会泄露什么、如何检查你自己的网站,见用户能在你的 JavaScript 里看到什么,以及如何保护它。

2026 年 5 月,我把两款流行混淆器的旗舰演示交给 Claude Code,只配了一份四段话的提示词。Claude Opus 4.6 把它还原成了干净源码,用了 10 分钟;Claude Opus 4.7 用了 20 分钟。那只是小演示,不是完整应用,而且这些模型如今已经落后当前一代。

你的定价规则、许可证校验、反欺诈规则和未发布的功能,一直都在 bundle 里。变的是谁能读懂它们,以及读得有多快。你还能控制的,是这些工作有多少能延续到你的下一个版本。

混淆后的 JavaScript 能被还原吗?

能。只要时间足够,任何混淆器的输出都能被还原,AfterPack 的也不例外。AfterPack 改变的是延续性:还原一个版本所做的工作,有多少还能用在下一个版本上。根据我们自己的测量(2026 年 9 月,六个种子 × 五个样本),反混淆器从一次构建里还原出的内容,在下一次构建上仍能对应上的不到 6%(测量方法)。

已经被读懂的逻辑也不会因此被忘掉:如果有人已经弄明白了你的折扣规则,新的一次构建并不能让他忘记。

能过期的,是建立在这次阅读之上的工具。剥掉许可证校验的脚本、绕过付费墙的补丁、从每个版本里抽取你评分规则的提取器:每一个都是针对某一次构建的结构写出来的。最流行的开源混淆器输出的形态是固定的,免费的公开反混淆器里就内置了针对这些形态的硬编码识别器,所以工具写一次,就能在之后每一次构建上继续用。

AfterPack 每次构建都从一个新的随机种子开始。标识符名称、编码后的字符串、解码器的签名、状态编号和被掩码的常量,全都会变,所以工具会硬编码的那些细节每次都不一样。把引擎放进 Worker 里运行,这个窗口就从一个版本缩短到一次请求。

AfterPack 里有什么?

一个 CLI、适配你已在使用的打包工具的插件、供 Workers 使用的 WebAssembly 版本、Pro 云端构建、一份展示每次构建保护了什么的报告,以及一个免费的网站扫描器。

项目AfterPack
是什么面向生产构建的 JavaScript 混淆器:它改写的是打包工具的产物,而不是你的源文件
引擎Rust,由 CLI 和插件在本地运行,或以 WebAssembly 形式(@afterpack/wasm)在你自己的 Worker 里运行
输出CLI 和插件默认每次构建都不同;只有需要字节完全一致时才固定种子
许可证CLI 和插件采用 Apache-2.0;引擎依据 AfterPack Engine License 免费使用
价格本地引擎免费;Pro 每月 49 美元起(套餐)
开始使用构建后运行 npx afterpack@latest,或使用框架插件

表格里没写到的:

  • 框架插件,支持 Next.js、Vite、webpack、Astro、Nuxt、SvelteKit、Svelte、Vue、Angular、Parcel、esbuild、Rollup 和 Electron。你平常的生产构建会直接输出混淆后的代码。
  • Pro:传入密钥,同样的调用就会在 AfterPack 的云端运行,并支持用指令把更重的保护集中到关键代码上。如果密钥或云端不可用,构建会直接失败,而不是悄悄发出保护更弱的代码。
  • Protection Map:一份 HTML 报告,展示你的原始源码,每个 token 都按它经过的变换量着色。它会在你的构建生成 source map 时写出;插件可以帮你打开这一选项。
  • 免费的安全扫描器,也可以通过 npx afterpack audit <url> 使用。

AfterPack 混淆后的输出长什么样?

标识符会消失,字符串字面量会被编码在一个运行时解码器后面;再往上加多少东西,取决于预设。light(默认)会编码字符串并改写语法,不添加任何结构层——这是大多数项目合适的基线。medium 会让生产代码明显更难跟踪;hard 面向定价、权限判断、许可证校验这类重要代码;extreme 设定各预设中最高的复杂度,最适合只针对一个函数或一个文件,而不是整个 bundle。

一个 139 字节的函数,混淆前:

1export function discount(plan, seats) {
2 if (plan === "team" && seats >= 10) return 0.2;
3 if (plan === "team") return 0.1;
4 return 0;
5}

混淆后,一次 npx afterpack@latest,默认 light 预设(2026 年 9 月 27 日):

1export function discount(N, O) {
2 if (N === Jr("T|P4") && O >= 10) return 0.2;
3 if (N === Jr("T|P4")) return 0.1;
4 return 0;
5}

"team" 不见了,换成了一段密文和一次解码器调用;再跑一次,名字、密文和解码器的签名全都会变。在 light 下,10、0.2、0.1 这样的数字仍然可读;medium 及以上还会把像这个 10 一样的整数常量掩码起来。解码器本身也要占一部分体积,所以这么小的文件,混淆后的比例会显得比真实 bundle 大得多:在真实 bundle 上,light 的输出按 gzip 计是输入的 1.9 到 2.4 倍(预设)。

把你自己的函数粘贴到 playground 里,看看每个预设会把它变成什么样——不用安装,也不用注册。

现在就试试 AfterPack

  • 粘贴代码:playground 会直接在浏览器里混淆你粘贴的任何代码,无需安装。
  • 扫描你的网站:安全扫描器会告诉你,你的生产环境 JavaScript 已经暴露了什么。
  • 一句提示词:交给任意编码 Agent——Add AfterPack to this project: read afterpack.dev/llms.txt, follow the quickstart for my framework, then run a production build and show me the Protection Map.
  • 一条命令:在下一次构建后运行 npx afterpack@latest。

在 Cloudflare Worker 里按请求混淆 JavaScript

@afterpack/wasm 以 WebAssembly 形式在你自己的 Worker 里运行引擎,每次调用都传入一个新种子,每个响应就会是不同方式混淆出来的代码:

1import { obfuscate } from "@afterpack/wasm";
2
3export default {
4 async fetch(request) {
5 const upstream = await fetch("https://example.com/app.js"); // your origin's bundle
6 if (!upstream.ok) return upstream;
7 const source = await upstream.text();
8 const result = await obfuscate(
9 { path: "app.js", source },
10 { preset: "hard", seed: crypto.randomUUID() },
11 );
12 return new Response(result.bytes, {
13 headers: { "content-type": "application/javascript" },
14 });
15 },
16};

如果我们在 Apple M2 Max 上用 Node 跑这个处理函数(2026 年 9 月 27 日),从本地源站提供那个 discount 文件:四次请求会得到四份不同的输出,每份都返回正确的折扣。模块预热之后,每次混淆都不到 4 ms;第一次调用要实例化引擎,大约 40 ms。这是一个 139 字节的输入;真实的 bundle 会消耗多得多的 CPU,而且每个响应都要付一次。Workers 指南介绍了各套餐的限制,以及什么时候每个轮换窗口缓存一个形态是更划算的选择。

完整的配置,包括 wrangler 配置、按时间窗口缓存一个形态以及真实的 curl 输出,见教程如何用 Cloudflare Workers 对每次请求混淆 JavaScript。

如何混淆 Next.js、Vite、webpack 或其他任何构建

在构建之后运行 CLI,或者为你的打包工具安装插件,让每次生产构建都输出混淆后的代码。CLI 无需任何配置;构建完成后在项目根目录运行:

npx afterpack@latest

它会找到你的构建产物(dist/、.next/、.output/、build/ 或 out/),原地改写并保留一份备份;npx afterpack@latest restore 可以撤销这次运行。

如果想让混淆成为构建本身的一部分,为你的打包工具安装插件:

npm install -D @afterpack/next # or @afterpack/vite, @afterpack/webpack

每个插件只需要一处很小的配置改动,比如用 withAfterpack(config) 包住你的 Next.js 配置;框架页面给出了从 Astro 到 Parcel 每个受支持打包工具的写法。想知道你的线上网站今天暴露了什么,先用扫描器跑一遍。

AfterPack 有哪些局限?

AfterPack 提高的是读懂你的代码、以及复用针对它的工具的成本;它无法对插桩运行中程序的人隐藏值,所以密钥以及任何授予访问权限的东西,都应该放在你的服务器上。它带来的好处则跟着你本来就在跑的构建一起来:每个版本都是一个新目标,不需要额外记住任何步骤。

AfterPack 接下来做什么?

接下来是网络层混淆:network transport cloaking 会让你的 API 请求和响应经过一个随每次构建变化的编解码器。跨模块混淆会把逻辑在模块边界之间连接起来,而 AfterPack on Workers for Platforms 会为每次请求提供新的形态,不需要安装任何东西。JavaScript 之后,下一步是 HTML 和 CSS。

AfterPack 常见问题

AfterPack 免费吗?

免费。CLI、框架插件和本地引擎都免费,你的源码永远不会离开你的机器。Pro 增加云端构建和按区域的指令,每月 49 美元起;注册的 Free 工作区每月有 10 MB 的 Pro 构建额度。完整对比见套餐与层级。

AfterPack 开源吗?

CLI 和框架插件是开源的,采用 Apache-2.0 协议,托管在 GitHub 上。它们运行的引擎依据 AfterPack Engine License 免费使用。

混淆会拖慢我的代码吗?

会有一些影响,预设越强影响越大。默认是 light。可以为整个项目提高预设,也可以用 Pro 指令只把 hard 或 extreme 用在需要的函数上。

AfterPack 和其他 JavaScript 混淆器有什么不同?

它通过你已在使用的打包工具的插件作用于生产构建,而且默认每次构建都生成不同的输出,所以针对一个版本写的反混淆器到下一个版本基本就失效了。构建时间、输出大小和延续性,与其他混淆器的并排实测,见对比页面。

混淆能隐藏 API 密钥吗?

不能。运行中的代码用到的任何东西,都能被在自己掌控的浏览器里运行它的人观察到,所以请把 API 密钥和其他秘密留在服务器上。不过编码确实能让密钥躲过 grep 和自动化的密钥扫描器,为你轮换一个意外发出去的密钥争取时间(最佳实践)。


发现了 bug,或者想要一个我们还没支持的打包工具?在 GitHub 上提一个 issue,附上你的打包工具和它的版本;我在那里看反馈。

你发布的代码,一直都是可以被读懂的。从今天起,有人从一个版本里学到的东西,不必再延续到下一个版本。

— Nikita

保持关注

关注 AfterPack,获取发布说明和技术文章。