# 适用于你的框架的 JavaScript 混淆

针对你的技术栈应安装哪个包、它在何处接入，以及它会写出哪些文件。

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

AfterPack 混淆的是打包工具产出的 JavaScript。安装对应你技术栈的包，平时的构建就会输出已混淆的结果。其他情况下，对构建输出运行 [`npx afterpack@latest`](https://www.afterpack.dev/zh/docs/cli) 即可。

## 框架矩阵

| 框架 | 包 | 接入方式 | 运行位置 | 构建输出 |
|---|---|---|---|---|
| [Next.js](https://www.afterpack.dev/zh/docs/frameworks/nextjs) | `@afterpack/next` | `withAfterpack(config)` | `next build` 内部的 `runAfterProductionCompile`，在 Next 写出 chunk 之后 | `.next/static/chunks`、`out/` |
| [Vite](https://www.afterpack.dev/zh/docs/frameworks/vite) | `@afterpack/vite` | 在 `plugins` 中加入 `afterpackVite()` | `generateBundle`，在流水线内 | `build.outDir` |
| [Webpack](https://www.afterpack.dev/zh/docs/frameworks/webpack) | `@afterpack/webpack` | `new AfterpackWebpackPlugin()` | `compilation.hooks.processAssets`，在流水线内 | `output.path` |
| [Rollup](https://www.afterpack.dev/zh/docs/frameworks/rollup) | `@afterpack/rollup` | 在 `plugins` 中加入 `afterpackRollup()` | `generateBundle`，在流水线内 | `output.dir` 或 `output.file` |
| [esbuild](https://www.afterpack.dev/zh/docs/frameworks/esbuild) | `@afterpack/esbuild` | 在 `plugins` 中加入 `afterpackEsbuild()` | `onEnd`，在 esbuild 写出文件之后 | `outdir` 或 `outfile` |
| [Astro](https://www.afterpack.dev/zh/docs/frameworks/astro) | `@afterpack/astro` | 在 `integrations` 中加入 `afterpack()` | Astro 的 Vite 配置中的 `@afterpack/vite` | `dist/` |
| [Svelte](https://www.afterpack.dev/zh/docs/frameworks/svelte) | `@afterpack/svelte` | 在 `plugins` 中加入 `afterpackSvelte()` | `@afterpack/vite` | `dist/` |
| [SvelteKit](https://www.afterpack.dev/zh/docs/frameworks/sveltekit) | `@afterpack/sveltekit` | 在 `sveltekit()` 之后加入 `afterpackSveltekit()` | `@afterpack/vite` | 适配器输出（`build/`） |
| [Vue 3](https://www.afterpack.dev/zh/docs/frameworks/vue) | `@afterpack/vue` | 在 `vue()` 之后加入 `afterpackVue()` | `@afterpack/vite` | `dist/` |
| [Nuxt 3](https://www.afterpack.dev/zh/docs/frameworks/nuxt) | `@afterpack/nuxt` | `modules: ["@afterpack/nuxt"]` | 挂在 Nuxt 的 Vite 配置上的 `@afterpack/vite` | `.output/public/_nuxt/` |
| [Angular v17+](https://www.afterpack.dev/zh/docs/frameworks/angular) | `@afterpack/angular` | 在 postbuild 脚本中调用 `afterpackAngular()` | 一次 postbuild 处理，在 `ng build` 写出文件之后 | `dist/<app>/browser` |
| [Electron](https://www.afterpack.dev/zh/docs/frameworks/electron) | `@afterpack/electron` | 用 `withAfterpack(config)` 包裹 `electron-vite` | 三个构建目标都运行 `@afterpack/vite`，共用一个种子 | 每个构建目标各自的 `out/` |
| [Parcel](https://www.afterpack.dev/zh/docs/frameworks/parcel) | `@afterpack/parcel-optimizer` | `.parcelrc` 的 `optimizers` 中的一项 | 一个 Parcel 2 Optimizer，逐 bundle 运行，在流水线内 | Parcel 的 `distDir` |

Astro、Svelte、SvelteKit、Vue、Nuxt 和 Angular 会自行安装 `@afterpack/vite`，或运行同一套共享的处理流程，因此你无需手动接入。

## 无插件的情况

| 技术栈 | 方案 |
|---|---|
| [Remix / React Router v7](https://www.afterpack.dev/zh/docs/frameworks/remix) | 基于 Vite 构建：使用 `@afterpack/vite`，或使用 CLI。 |
| [纯 JS](https://www.afterpack.dev/zh/docs/frameworks/plain) | 没有可接入的打包工具：运行 `npx afterpack@latest <dir>`。 |

## 每个集成都会做什么

默认行为见[快速开始](https://www.afterpack.dev/zh/docs/quickstart#what-a-build-does-by-default)。除此之外，所有插件和 CLI 还共享以下行为：

- **除非声明为开发构建，否则每次构建都是[生产构建](https://www.afterpack.dev/zh/docs/config#build-mode)。** 只有 `build.mode=development` 或 `NODE_ENV=development` 才会产生开发构建，Parcel 则沿用它自己的模式。生产构建不会写出 [source map](https://www.afterpack.dev/zh/docs/config#sourceMap-enabled)，还会删除打包工具写出的 map，包括 CSS map。随产物一起发布的 map 会让混淆被还原。
- **相同的[产物](https://www.afterpack.dev/zh/docs/cli#files)。** map 开启时（默认仅在构建产出了 source map 且不在 CI 中运行时开启），一份合并的 [`protectionMap.html`](https://www.afterpack.dev/zh/docs/config#protectionMap-enabled)（Parcel 上每个 bundle 一份）写入已被 gitignore 的 `.afterpack/`；开启 map 时，每个文件旁边还会有一个 `.map`。`.afterpack/` 自带一个 `.gitignore`；你的 `.gitignore` 从不会被修改。[`build.backup`](https://www.afterpack.dev/zh/docs/config#build-backup) 有两种形态：CLI 在每次运行时把你的原始文件镜像到 `.afterpack/backups/`；而直接混淆磁盘上文件的插件（`@afterpack/next`、`@afterpack/esbuild`、`@afterpack/angular`）在你要求时，会在输出旁写出一个 `.backup.<hash>` 文件。流水线内的插件没有已写出的文件可供备份放在旁边，你要求时它们会发出警告。
- **内容哈希文件名跟随混淆后的字节。** 每个插件都根据文件内容加上种子、引擎版本和你的设置来命名混淆后的文件，因此同一个文件名永远不会对应两个不同的文件。CLI 在 Next.js、Angular、Vite 和 webpack 构建上也这样做，在其他任何输出上则保留打包器写下的文件名。参见[文件名与缓存](https://www.afterpack.dev/zh/docs/builds#file-names-and-caching)。
- **一个开关即可跳过运行。** [`build.autorun: false`](https://www.afterpack.dev/zh/docs/config#build-autorun) 保留已安装的插件，但跳过引擎。
- **插件从你的源码中读取指令**，凡是有可供读取的钩子的集成都如此。[Angular](https://www.afterpack.dev/zh/docs/frameworks/angular) 则直接拒绝该键：它的构建器是封闭的，处理流程只能看到已经压缩过的输出。CLI 出于同样的原因拒绝该键。指令是 [Pro](https://www.afterpack.dev/zh/docs/pro) 功能。

## 下一步

- [快速开始](https://www.afterpack.dev/zh/docs/quickstart)：选择技术栈并构建。
- [构建与 CI](https://www.afterpack.dev/zh/docs/builds)：种子、开发环境与生产环境的区别、原样提升同一份字节。
- [配置](https://www.afterpack.dev/zh/docs/config)：每个选项以及在何处设置。
