# Часті запитання про обфускацію JavaScript

Найпоширеніші запитання про AfterPack і короткі відповіді на кожне в кількох абзацах.

Source: https://www.afterpack.dev/uk/docs/faq

Загальні запитання — що таке AfterPack, чи він безкоштовний, чи не зламає він ваш застосунок — розібрано в [FAQ на головній сторінці](https://www.afterpack.dev/uk/#faq). Ця сторінка про деталі на рівні збірки.

## Чим Free відрізняється від Pro?

Free застосовує повний конвеєр однаково до всього бандла. Pro додає прицільність: ви [позначаєте ділянку](https://www.afterpack.dev/uk/docs/directives), і посилену обробку отримує лише цей код. Повну матрицю можливостей і ціни див. на сторінці [Тарифи](https://www.afterpack.dev/uk/docs/tiers).

## Чи потрібен мені плагін для фреймворку?

Для [фреймворку з повноцінною підтримкою](https://www.afterpack.dev/uk/docs/frameworks) так. [Встановіть плагін](https://www.afterpack.dev/uk/docs/quickstart#pick-your-framework) як dev-залежність і додайте один рядок у конфігурацію, і ваша **звичайна збірка** видаватиме обфускований результат. Де саме працює рушій, залежить від бандлера: Vite, Rollup, webpack і Parcel обфускують у власному конвеєрі бандлера, [Next.js](https://www.afterpack.dev/uk/docs/frameworks/nextjs) обфускує з хука всередині `next build`, а esbuild і Angular запускають окремий прохід, щойно їхня збірка запише результат.

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

Для чистих бандлерів або [стеків без плагіна](https://www.afterpack.dev/uk/docs/cli) натомість вкажіть [CLI](https://www.afterpack.dev/uk/docs/cli) на результат вашої збірки:

```bash
npx afterpack@latest dist/
```

В обох випадках AfterPack працює строго після збірки, на її результаті. [Каталог збірки](https://www.afterpack.dev/uk/docs/cli#usage) необов'язковий: без нього CLI сам визначить результат вашої збірки. CLI також є шляхом для [CI](https://www.afterpack.dev/uk/docs/builds) і для разових ручних запусків на фреймворках, які мають плагін.

## Чому той самий код дає різний результат у кожній збірці?

Це [поліморфізм між збірками](https://www.afterpack.dev/uk/docs/glossary#per-build-polymorphism), і це основний захист. Зі стандартним випадковим [сідом](https://www.afterpack.dev/uk/docs/config#seed) дві збірки одного й того самого вхідного коду виходять структурно різними. Статичний деобфускатор, який вивчив форму збірки N, не отримує нічого, що можна повторно використати для збірки N+1, тож регулярна перезбірка продакшну щоразу обнуляє прогрес зловмисника.

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

```bash
npx afterpack@latest dist/ --seed=git
```

Модель релізів така: dev-збірки не обфускуються, щоб ітерувати швидко; продакшн збирає обфускований артефакт **один раз** і просуває ті самі байти через qa, preprod і prod. Див. [Збірки та CI](https://www.afterpack.dev/uk/docs/builds).

## Free — це лише перейменування?

Ні. Free запускає весь рушій. Пресет за замовчуванням `light` перейменовує ідентифікатори й кодує кожен рядковий літерал, який може переписати. Починаючи з `medium`, Free також сплощує потік керування, зливає та роздуває логіку і матеріалізує константи, усе в межах файлу. Такий результат перебудовано, а не просто перейменовано, і він залишається в поліноміально-ін'єктивному [класі відновлення](https://www.afterpack.dev/uk/docs/reversal-classes): оригінальну структуру можна відновити лише ціною реальних зусиль, які доводиться повторювати з кожною збіркою.

## Чи діє директива лише на один рядок?

Ні. Директива охоплює цілу **[ділянку](https://www.afterpack.dev/uk/docs/directives#what-you-can-set)**, а не лише власний рядок. Відкрийте блок директивою [`/* @afterpack preset=hard */`](https://www.afterpack.dev/uk/docs/config#preset) окремо на рядку над функцією і закрийте його [`/* @afterpack end */`](https://www.afterpack.dev/uk/docs/directives#what-you-can-set) після закривальної дужки, і вона покриє всю функцію разом із тілом:

```ts
/* @afterpack preset=hard */
export function checkLicense(token: string) {
  // the entire function body is covered
}
/* @afterpack end */
```

Це [блокова форма](https://www.afterpack.dev/uk/docs/directives#writing-one): відкривальний коментар окремо на своєму рядку, закритий парним `/* @afterpack end */`. Для одного значення вбудована директива [`/* @afterpack preset=extreme */`](https://www.afterpack.dev/uk/docs/config#preset) покриває решту свого рядка: літерал або вираз одразу після неї. Повну граматику див. у [Директивах](https://www.afterpack.dev/uk/docs/directives#writing-one).

## Що буде, якщо хмара Pro недоступна?

Вона повторює спроби із затримкою, що зростає, а потім [зупиняє збірку з помилкою (fail closed)](https://www.afterpack.dev/uk/docs/diagnostics#fail-closed-no-exceptions): збій хмари ламає CI, а не випускає менше захисту, ніж ви просили.

Якщо вам взагалі не потрібна стороння залежність у процесі збірки, запускайте [Free](https://www.afterpack.dev/uk/docs/pro#what-free-already-gives-you) локально: він ніколи не звертається до мережі. Див. [Режими розгортання](https://www.afterpack.dev/uk/docs/deployment-modes).

## Як працюють source map?

Source map від AfterPack пов'язують обфускований результат із вашим оригінальним вихідним кодом. Вони корисні для локального налагодження. Ніколи не випускайте їх у продакшн: публічний `.map` дає зловмиснику прямий шлях до вихідного коду, який ви щойно обфускували.

AfterPack за замовчуванням не пускає їх у ваш продакшн-бандл: [генерацію source map](https://www.afterpack.dev/uk/docs/config#sourceMap-enabled) вимкнено в [продакшн-збірці](https://www.afterpack.dev/uk/docs/config#build-mode), коментар [`//# sourceMappingURL=`](https://www.afterpack.dev/uk/docs/config#sourceMap-emitUrl) прибирається, а source map, які записав ваш бандлер, видаляються, зокрема CSS-карти. Кожна збірка є продакшн-збіркою, якщо вона не позначена як збірка для розробки, і локальний `npx afterpack` теж. Див. [Найкращі практики](https://www.afterpack.dev/uk/docs/best-practices).

## Чи можна використовувати AfterPack у CI?

Так. Для фреймворку з повноцінною підтримкою плагін працює як частина вашої звичайної збірки, тож ваш наявний крок збірки вже видає обфускований результат. Для інших стеків додайте [`npx afterpack@latest <path>`](https://www.afterpack.dev/uk/docs/cli#usage) як крок після збірки.

Закріпіть [сід](https://www.afterpack.dev/uk/docs/config#seed) за ідентифікатором релізу, щоб артефакти були відтворюваними, зберіть обфускований результат один раз і просувайте ті самі байти через ваші середовища. Проводьте [аудит](https://www.afterpack.dev/uk/docs/audit) кожного релізу і додавайте [Protection Map](https://www.afterpack.dev/uk/docs/protection-map) як артефакт CI. Повний приклад конвеєра див. у [Збірки та CI](https://www.afterpack.dev/uk/docs/builds).

## Чи сповільнює обфускація мій код?

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

Що важчий [пресет](https://www.afterpack.dev/uk/docs/presets#the-ladder), то дорожче: кожен щабель відповідає вищій [`complexity`](https://www.afterpack.dev/uk/docs/config#complexity), а типовий — `light`. Важчий пресет застосовує більше трансформацій; це не виміряне посилення захисту. Тримайте глобальний пресет на `light`, якщо важчий не виправдовує своєї ціни, і залиште `extreme` для [ділянок](https://www.afterpack.dev/uk/docs/directives), які ви позначаєте. Драбину пресетів і значення наведено на сторінці [Пресети](https://www.afterpack.dev/uk/docs/presets#the-ladder).

## Як захистити API-ключі та логіку ліцензування?

Позначте їх. Поставте вбудовану директиву [`/* @afterpack preset=extreme */`](https://www.afterpack.dev/uk/docs/config#preset) перед секретним літералом, а функцію, яка перевіряє ліцензію, обгорніть блоком [`/* @afterpack preset=hard */`](https://www.afterpack.dev/uk/docs/config#preset) … [`/* @afterpack end */`](https://www.afterpack.dev/uk/docs/directives#what-you-can-set):

```ts
const LICENSE_SECRET = /* @afterpack preset=extreme */ "YOUR_SECRET";

/* @afterpack preset=hard */
export function checkLicense(token: string) {
  /* ... */
}
/* @afterpack end */
```

[`preset=extreme`](https://www.afterpack.dev/uk/docs/config#preset) піднімає цю ділянку до [цільової складності](https://www.afterpack.dev/uk/docs/config#complexity) 25 з примусово увімкненим [мінімальним кодуванням рядків](https://www.afterpack.dev/uk/docs/config#strings-encode), тож літерал закодовано, а не випущено відкритим текстом. Він усе ще присутній у результаті, і програма відновлює його в момент використання. Щоб повністю прибрати з результату літерал, з яким ваш код порівнює значення, увімкніть [`transforms.comparisonHardening.enabled`](https://www.afterpack.dev/uk/docs/config#transforms-kind-enabled): порівняння стає перевіркою одностороннього дайджесту, і в результат потрапляє лише дайджест. У будь-якому разі зловмисник, який запускає код в інструментованому середовищі виконання, усе одно може дістатися до значення (див. наступне запитання). Ці директиви підвищують вартість статичного відновлення в кожному релізі. Вони не роблять цінний секрет чимось, що безпечно тримати на клієнті. Повний підхід описано в [Найкращих практиках](https://www.afterpack.dev/uk/docs/best-practices).

## Чи може той, хто запускає мій код, витягти секрет?

Так. Наполегливий зловмисник, який запускає ваш код в інструментованому середовищі виконання, може дістатися до будь-якого секрету, який використовує сам код. Жоден обфускатор на етапі збірки цього не змінює: якщо запущеній програмі потрібне значення для роботи, його може побачити той, хто пропатчить середовище виконання, перехопить потрібний виклик або зробить знімок heap у потрібний момент.

AfterPack робить значення невидимим для дешевших атак: статичного читача і «сліпої» LLM, яка пояснює код, не запускаючи його. [Нематеріалізація](https://www.afterpack.dev/uk/docs/glossary#non-materialization) повністю прибирає захищений перевіркою літерал з артефакту, [мінімальне кодування рядків](https://www.afterpack.dev/uk/docs/config#strings-encode) не дає решті лишитися відкритим текстом, а [поліморфізм між збірками](https://www.afterpack.dev/uk/docs/glossary#per-build-polymorphism) ламає інструменти, написані під шаблони однієї збірки, на наступній. Той, хто запускає код, усе одно може прочитати значення, які він використовує.

Обфускація підвищує вартість статичного та повторного видобування клієнтського секрету. Єдиний спосіб тримати цінний секрет поза досяжністю зловмисника — ніколи не відправляти його на клієнт: тримайте його на сервері, і нехай рішення ухвалює сервер. Використовуйте [`preset=extreme`](https://www.afterpack.dev/uk/docs/config#preset) для секретів, які справді не можна перенести на сервер, і сприймайте це як підвищення вартості атаки, а ніколи не як сейф.

## Які фреймворки підтримуються?

Ці стеки мають опублікований плагін: [Next.js](https://www.afterpack.dev/uk/docs/frameworks/nextjs), [Vite](https://www.afterpack.dev/uk/docs/frameworks/vite), [Webpack](https://www.afterpack.dev/uk/docs/frameworks/webpack), [Rollup](https://www.afterpack.dev/uk/docs/frameworks/rollup), [esbuild](https://www.afterpack.dev/uk/docs/frameworks/esbuild), [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 3](https://www.afterpack.dev/uk/docs/frameworks/vue), [Nuxt 3](https://www.afterpack.dev/uk/docs/frameworks/nuxt), [Angular v17+](https://www.afterpack.dev/uk/docs/frameworks/angular), [Electron](https://www.afterpack.dev/uk/docs/frameworks/electron) і [Parcel](https://www.afterpack.dev/uk/docs/frameworks/parcel). Плагін знає власний каталог виводу, тож його нікуди не треба спрямовувати.

[Remix](https://www.afterpack.dev/uk/docs/frameworks/remix) і [чистий JS](https://www.afterpack.dev/uk/docs/frameworks/plain) обробляються через [CLI](https://www.afterpack.dev/uk/docs/cli#usage) після збірки, де ви самі вказуєте каталог (`npx afterpack@latest dist/`; Next.js пише в `.next/`, Nuxt у `.output/`). Повну матрицю та налаштування для кожного стека див. у [Фреймворках](https://www.afterpack.dev/uk/docs/frameworks), а публічний [Security Scanner](https://www.afterpack.dev/uk/security-scanner) покаже, як виглядає захист на реальному бандлі.

## Де поставити запитання, повідомити про баг чи запропонувати функцію?

На GitHub. Запитання та пропозиції — у [GitHub Discussions](https://github.com/afterpack-dev/afterpack/discussions); баги — у [GitHub Issues](https://github.com/afterpack-dev/afterpack/issues). Проблему безпеки надсилайте на **security@afterpack.dev**, а не в публічне обговорення, див. [SLA, SLO та підтримка](https://www.afterpack.dev/uk/docs/sla#security-disclosure).

## Далі

- [Швидкий старт](https://www.afterpack.dev/uk/docs/quickstart): встановлення, збірка і реліз за кілька хвилин
- [Тарифи](https://www.afterpack.dev/uk/docs/tiers): Free проти Pro, можливість за можливістю
- [Конфігурація](https://www.afterpack.dev/uk/docs/config): кожен параметр і якою формою його можна задати
- [Директиви](https://www.afterpack.dev/uk/docs/directives): граматика `@afterpack` і які ключі застосовуються
- [Пресети](https://www.afterpack.dev/uk/docs/presets): шкала з п'яти щаблів
- [Найкращі практики](https://www.afterpack.dev/uk/docs/best-practices): секрети, source map і CI
