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

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

Source: https://www.afterpack.dev/uk/docs/frameworks/vite

`@afterpack/vite` є еталонною інтеграцією. [Astro](https://www.afterpack.dev/uk/docs/frameworks/astro), [Svelte](https://www.afterpack.dev/uk/docs/frameworks/svelte), [SvelteKit](https://www.afterpack.dev/uk/docs/frameworks/sveltekit), [Vue](https://www.afterpack.dev/uk/docs/frameworks/vue) і [Nuxt](https://www.afterpack.dev/uk/docs/frameworks/nuxt) обгортають її, тож усе, що описано на цій сторінці, стосується й цих пакетів.

Плагін зчитує [директиви `@afterpack`](https://www.afterpack.dev/uk/docs/directives) з вашого вихідного коду, а потім запускає рушій у `generateBundle`, коли готовий бандл перебуває в пам'яті і Vite ще нічого з нього не записав.

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

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

```ts
// 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`](https://www.afterpack.dev/uk/docs/protection-map): одну об'єднану мапу для збірки, яка записується в `.afterpack/`, внесений у gitignore, у корені вашого проєкту, коли мапу ввімкнено. За замовчуванням її вимкнено; див. розділ [Перевірка](#verify). Вона містить ваш оригінальний вихідний код. Ніколи не допускайте, щоб вона потрапила в каталог, який роздається сервером.
- `foo.js.map`: [source map](https://www.afterpack.dev/uk/docs/config#sourceMap-enabled), коли мапи ввімкнено. Коли мапи вимкнено, а це значення за замовчуванням для продакшну, власний запис мапи Vite відкидається, а не записується поруч з обфускованим чанком.

Файлу `foo.backup.<hash>.js` тут немає. Обфусковані байти повертаються в бандл, тож немає виданого файлу, поруч з яким могла б лежати резервна копія, і [`build.backup: true`](https://www.afterpack.dev/uk/docs/config#build-backup) видає попередження замість того, щоб її записати.

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

## Перевірка

[Protection Map](https://www.afterpack.dev/uk/docs/protection-map) за замовчуванням записується, коли Vite видає source map і збірка не працює в CI (`CI=true` або `CI=1`); [продакшн-збірка](https://www.afterpack.dev/uk/docs/config#build-mode) її не вимикає. Vite не видає source map, якщо не задано `build.sourcemap`, тож у звичайній збірці мапа за замовчуванням вимкнена. Запитайте її явно, коли хочете її переглянути:

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

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

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

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

> **Ніколи не публікуйте source map у продакшн**
>
> Файл `.map` веде до вашого оригінального вихідного коду. Ніколи не розгортайте його.

## Параметри

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

`preset` і `complexity` задають різні речі. [Пресет](https://www.afterpack.dev/uk/docs/presets) є набором: він задає разом цільову складність, загальний множник розміру результату та [бюджет роздування](https://www.afterpack.dev/uk/docs/config#inflation-max). `complexity` є одним числом усередині цього набору:

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

## Директиви

Директиви — це можливість тарифу [Pro](https://www.afterpack.dev/uk/docs/pro). У [збірці Free](https://www.afterpack.dev/uk/docs/directives#free-builds) директива, яка посилює захист, зупиняє збірку з помилкою `DIAG_PRO_DIRECTIVE_REQUIRES_KEY`.

Плагін зчитує директиви з вашого вихідного коду до того, як будь-який мініфікатор прибере коментарі. [Граматика](https://www.afterpack.dev/uk/docs/directives#writing-one) допускає лише блокові коментарі:

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

Рядкові коментарі `// @afterpack …` не скануються, і про них повідомляє [діагностика](https://www.afterpack.dev/uk/docs/diagnostics).

Кожен ключ, який може задати директива, наведено на сторінці [Директиви](https://www.afterpack.dev/uk/docs/directives#what-you-can-set).

Зчитування пропускає `node_modules` і файли, що не є JS/TS. Директива всередині однофайлового компонента `.vue` чи `.svelte` не зчитується. Натомість розмістіть її у звичайному модулі `.ts`/`.js`, який імпортує компонент. Задайте [`directives.enabled: false`](https://www.afterpack.dev/uk/docs/config#directives-enabled), щоб повністю пропустити сканування.

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

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

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

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

Кожна збірка Vite обфускує лише власний бандл, тож окремі збірки є окремими проходами, навіть коли вони пишуть в один каталог. Закріпіть для них однаковий [`seed`](https://www.afterpack.dev/uk/docs/config#seed), якщо в них спільний контракт під час виконання.

### Імена з хешем вмісту

Ім'я кожного чанка [слідує за його обфускованими байтами](https://www.afterpack.dev/uk/docs/builds#file-names-and-caching). JavaScript-файл, що потрапляє в бандл як звичайний ассет, а не як чанк, зібраний Vite, зберігає ім'я, яке Vite дав його необфускованим байтам, і збірка попереджає: імпортуйте його як модуль або роздавайте без довготривалого кешування. Попередньо стиснуті копії `.gz` і `.br` у бандлі генеруються заново з обфускованих байтів, а попередньо стиснута копія в будь-якому іншому форматі завершує збірку помилкою.

### Цілісність підресурсів

Плагін Vite, що обчислює хеші цілісності підресурсів, відхиляється, бо його атрибути `integrity` не збігалися б з обфускованими файлами. Приберіть його й обчисліть цілісність за розгорнутими файлами після збірки.

## Далі

- [Фреймворки](https://www.afterpack.dev/uk/docs/frameworks): повна матриця.
- [Збірки та CI](https://www.afterpack.dev/uk/docs/builds): сіди, dev проти prod, просування тих самих байтів.
- [Protection Map](https://www.afterpack.dev/uk/docs/protection-map): як читати звіт.
- [Конфігурація](https://www.afterpack.dev/uk/docs/config): поверхня конфігурації рушія.
- [Директиви](https://www.afterpack.dev/uk/docs/directives): кожен ключ позначки і що він робить.
- [Пресети](https://www.afterpack.dev/uk/docs/presets): драбина з п'яти щаблів.
