# 混淆一个 Nuxt 应用

@afterpack/nuxt 是一个 Nuxt 3 模块，在 Nuxt 的 Vite 配置上注册 @afterpack/vite。

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

Nuxt 3 用 Vite 打包,而 AfterPack 是在**打包工具**这一层做集成的,因此 `@afterpack/nuxt` 是一个很薄的 Nuxt 模块:它调用 `addVitePlugin`,在 Nuxt 的 Vite 配置上注册 [`@afterpack/vite`](https://www.afterpack.dev/zh/docs/frameworks/vite),客户端打包产物会在 Vite 的 `generateBundle` 阶段、也就是构建写入之前被混淆。

Nuxt 2 项目用 webpack 构建。那里请改用 [`@afterpack/webpack`](https://www.afterpack.dev/zh/docs/frameworks/webpack)。

## 安装

```bash
npm install -D @afterpack/nuxt
```

```ts
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ["@afterpack/nuxt"],
  afterpack: {
    seed: "git",
  },
});
```

选项位于 `afterpack` 配置键下。

## 构建

`nuxt generate`(静态)或 `nuxt build`(SSR)现在会生成混淆后的输出。`nuxt dev` 不受影响,因为插件只运行在 Vite 的 `generateBundle` 上。每个 Vite 环境(客户端和服务端)都会注册一个独立的 `@afterpack/vite` 插件实例,各自在 Vite 写入之前混淆自己的打包产物。

### 静态与服务端

- **静态 / 预渲染**(`nuxt generate`):`.output/public/_nuxt/` 中预渲染的客户端打包产物会被混淆。这是发布受保护客户端代码的推荐形态。
- **服务端(SSR)**:客户端打包产物按同样的方式被混淆;Nitro 服务端打包产物是你自己的部署产物。

当你希望一次发布的多条客户端分支由同一个种子构建出来,或者一次构建必须逐字节可复现(命中缓存、黄金快照)时,固定 [`seed: "git"`](https://www.afterpack.dev/zh/docs/config#seed)。[构建与 CI](https://www.afterpack.dev/zh/docs/builds) 讲了这个取舍。Nuxt 每次构建也会生成一个新的 `buildId`。

## 验证

```ts
export default defineNuxtConfig({
  modules: ["@afterpack/nuxt"],
  afterpack: { protectionMap: { enabled: true } },
});
```

把合并后的 [Protection Map](https://www.afterpack.dev/zh/docs/protection-map) 写入已被 gitignore 的 `.afterpack/protectionMap.html`。source map 的副作用和处理规则与 [`@afterpack/vite`](https://www.afterpack.dev/zh/docs/frameworks/vite#verify) 相同。

*(live Protection Map demo embed — see https://www.afterpack.dev/protection-map-demo)*

要检查一次部署，请在上传前运行 `npx afterpack@latest verify .output/public`。Nitro 会把受保护的客户端构建复制到这里，[`verify`](https://www.afterpack.dev/zh/docs/cli#afterpack-verify-dir) 按构建的保护回执检查这份副本，并点名任何被改动的文件。

## 选项

每一个[配置键](https://www.afterpack.dev/zh/docs/config)都可以放在 `afterpack` 配置键下传入,并会逐字转发给 [`@afterpack/vite`](https://www.afterpack.dev/zh/docs/frameworks/vite#options),例如 `afterpack: { preset: "hard", complexity: 40 }`。类型别名 `AfterpackNuxtOptions` 就是 `AfterpackViteOptions`。

## 指令

指令是 [Pro](https://www.afterpack.dev/zh/docs/pro) 功能。在 [Free 构建](https://www.afterpack.dev/zh/docs/directives#free-builds)中，会提高保护强度的指令会让构建停止，并报错 `DIAG_PRO_DIRECTIVE_REQUIRES_KEY`。

`.vue` 文件内部的 `/* @afterpack … */` 标记不会被捕获。请把指令放在组件所导入的普通 `.ts`/`.js` 模块里(一个 composable、一个 `utils/` 文件)。

## 下一步

- [框架](https://www.afterpack.dev/zh/docs/frameworks):完整对照表。
- [Vite](https://www.afterpack.dev/zh/docs/frameworks/vite):实际执行工作的插件。
- [Vue](https://www.afterpack.dev/zh/docs/frameworks/vue):一个普通的 Vue 3 + Vite 应用。
- [Protection Map](https://www.afterpack.dev/zh/docs/protection-map):如何阅读这份报告。
- [构建与 CI](https://www.afterpack.dev/zh/docs/builds):种子、开发环境与生产环境的区别、提升同一份字节。
