混淆一个 Vue 应用

@afterpack/vue 为 Vue 3 项目包装了 @afterpack/vite:在 vite.config.ts 中加一行插件。

Vue 3 应用用 Vite 构建,而 AfterPack 是在**打包工具**这一层做集成的,因此 @afterpack/vue 是一个很薄的包装器:afterpackVue(options) 就是 afterpackVite(options),只是为了在 Vue 项目里更容易被发现而单独命名。

旧版 Vue CLI 项目用 webpack 而不是 Vite 构建。那里请使用 @afterpack/webpack。

安装

$ npm install -D @afterpack/vue
// vite.config.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import { afterpackVue } from "@afterpack/vue";

export default defineConfig({
  plugins: [vue(), afterpackVue()],
});

把它放在 vue() 之后。具名导出是 afterpackVue;该包还重新导出了 afterpackVite 和 AfterpackViteOptions 类型。

构建

vite build 现在会生成混淆后的输出。vite dev 不受影响,因为插件只运行在构建的 generateBundle 上,也就是在 Vite 写入打包产物之前。

验证

afterpackVue({ protectionMap: { enabled: true } });

把合并后的 Protection Map 写入已被 gitignore 的 .afterpack/protectionMap.html。source map 的副作用和处理规则与 @afterpack/vite 相同。

entitlements.jslight · complexity 5Open full size
entitlements.js, 54 lines, built at the light preset with a directive around the signature check. Click any token to see what was applied to it.

选项

每一个配置键都可以作为选项对象在这里传入,并会逐字转发给 @afterpack/vite。类型别名 AfterpackVueOptions 就是 AfterpackViteOptions。

afterpackVue({ seed: "git", preset: "medium" });

指令

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

// src/composables/useLicense.ts
/* @afterpack preset=hard */
export function verify(token: string) {
  // ...
}
/* @afterpack end */

无论如何,每一个生成的 chunk 都会被混淆;只有指令需要放在普通模块里。

下一步

  • 框架:完整对照表。
  • Vite:实际执行工作的插件。
  • Nuxt:基于同一个插件的 Nuxt 3 模块。
  • Protection Map:如何阅读这份报告。
  • 构建与 CI:种子、开发环境与生产环境的区别、提升同一份字节。