Обфускація збірки Vite

@afterpack/vite обфускує вашу збірку в generateBundle, до того як Vite її запише. Це еталонна інтеграція, яку обгортає кожен інший пакет сімейства Vite.

@afterpack/vite є еталонною інтеграцією. Astro, Svelte, SvelteKit, Vue і Nuxt обгортають її, тож усе, що описано на цій сторінці, стосується й цих пакетів.

Плагін зчитує директиви @afterpack з вашого вихідного коду, а потім запускає рушій у generateBundle, коли готовий бандл перебуває в пам'яті і Vite ще нічого з нього не записав.

Встановлення

$ npm install -D @afterpack/vite
// vite.config.ts
import { defineConfig } from "vite";
import { afterpackVite } from "@afterpack/vite";

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

Збірка

Це все налаштування. Тепер npm run build видає обфускований результат; vite dev не зачіпається, бо плагін діє лише в generateBundle збірки. Vite записує обфусковані чанки і ніколи не записує оригінали, а невдала обфускація залишає outDir таким, яким він був.

Обфускується те, що зібрав Vite: кожен чанк у вихідному бандлі. Файли, які Vite копіює без змін із publicDir у каталог виводу, не збираються, не входять до бандла і не зачіпаються. Усе, що потребує захисту, пропускайте через бандлер.

Плагін записує:

  • protectionMap.html: одну об'єднану мапу для збірки, яка завжди записується в .afterpack/, внесений у gitignore, у корені вашого проєкту. Вона містить ваш оригінальний вихідний код. Ніколи не допускайте, щоб вона потрапила в каталог, який роздається сервером.
  • foo.js.map: source map, коли мапи ввімкнено. Коли мапи вимкнено, а це значення за замовчуванням для продакшну, власний запис мапи Vite відкидається, а не записується поруч з обфускованим чанком.

Файлу foo.backup.<hash>.js тут немає. Обфусковані байти повертаються в бандл, тож немає виданого файлу, поруч з яким могла б лежати резервна копія, і build.backup: true видає попередження замість того, щоб її записати.

.afterpack/ має власний .gitignore, тож плагін ніколи не редагує ваш власний. Він попереджає, якщо артефакт потрапляє під шлях, який роздається сервером.

Перевірка

Protection Map за замовчуванням записується, коли Vite видає source map і збірка не працює в CI (CI=true або CI=1); продакшн-збірка її не вимикає. Vite не видає source map, якщо не задано build.sourcemap, тож у звичайній збірці мапа за замовчуванням вимкнена. Запитайте її явно, коли хочете її переглянути:

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

Якщо build.sourcemap не задано, це також вмикає власні source map Vite, щоб мапа могла відобразити ваш оригінальний вихідний код. Без мапи, яку можна знайти, плагіну нема з чого відображати оригінальний вихідний код, і він про це повідомляє.

Звіт записується в .afterpack/protectionMap.html. Він містить увесь ваш вихідний код. Ніколи не комітьте його і не роздавайте з сервера, переглядайте його лише локально.

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.
Ніколи не публікуйте source map у продакшн

Файл .map веде до вашого оригінального вихідного коду. Ніколи не розгортайте його.

Параметри

Будь-який ключ конфігурації можна передати тут в об'єкті параметрів, наприклад afterpackVite({ preset: "hard", complexity: 40 }). Усі вони необов'язкові. Іменований експорт: afterpackVite.

preset і complexity задають різні речі. Пресет є набором: він задає разом цільову складність, загальний множник розміру результату та бюджет роздування. complexity є одним числом усередині цього набору:

afterpackVite({ preset: "hard", complexity: 40 }); // hard's size limits, target 40

Директиви

Плагін зчитує директиви з вашого вихідного коду до того, як будь-який мініфікатор прибере коментарі. Граматика допускає лише блокові коментарі:

/* @afterpack preset=hard */
function verifyLicense(token) {
  // ...
}
/* @afterpack end */

Рядкові коментарі // @afterpack … не скануються, і про них повідомляє діагностика.

Кожен ключ, який може задати директива, наведено на сторінці Директиви.

Зчитування пропускає node_modules і файли, що не є JS/TS. Директива всередині однофайлового компонента .vue чи .svelte не зчитується. Натомість розмістіть її у звичайному модулі .ts/.js, який імпортує компонент. Задайте directives.enabled: false, щоб повністю пропустити сканування.

Особливі випадки

Режим бібліотеки

Результат build.lib є публічним контрактом. AfterPack працює з готовим бандлом, тож експортовані імена зберігаються; внутрішні частини все одно перейменовуються та перебудовуються.

Кілька виводів

Кожна збірка Vite обфускує лише власний бандл, тож окремі збірки є окремими проходами, навіть коли вони пишуть в один каталог. Закріпіть для них однаковий seed, якщо в них спільний контракт під час виконання.

Далі