Пресети обфускації

П'ять рівнів захисту від minify до extreme, цільова складність, яку задає кожен, і що вже гарантує стандартний пресет без конфігурації (light).

Пресет — це іменований набір трансформацій із відомою ціною в розмірі та часі виконання. Важчий пресет застосовує більше трансформацій; це не виміряне посилення захисту. Одна назва задає цільову складність; розмір результату випливає з цієї цілі. Явне задання complexity перекриває ціль, а значення, задане напряму, завжди застосовується до кожного токена, навіть на light.

The five obfuscation presets ranked by complexity target, with light marked as the defaultextremetarget 25hardtarget 12mediumtarget 7lighttarget 5DEFAULTminifytarget 0Zero config gives you light: string literals encoded. Step up per project.

Шкала

ПресетcomplexityТиповий розмір після gzipМінімум для рядківКоли обирати
minify01.09x–1.17xвимк.Без обфускації. Ідентифікатори перейменовано, а код стиснуто; рядкові літерали залишаються читабельними.
light51.29x–1.60xувімк.За замовчуванням. Додає до minify кодування рядків і переписує синтаксис, без структурних шарів. Правильний пресет для всього бандла застосунку.
medium76.04x–8.33xувімк.Код, за яким має бути помітно важче стежити. На всьому бандлі застосунку він у рази збільшує час запуску (ціна завантаження), тож спершу виміряйте свої сторінки.
hard126.62x–9.23xувімк.Код, що має значення: ціноутворення, обмеження доступу, перевірки ліцензій, клієнтська бізнес-логіка. Націлюйте його на цей код за допомогою директиви; на всьому бандлі він коштує більше, ніж medium.
extreme258.25x–11.19xувімк.Найвища застосовувана складність. Націлюйте його на файл або ділянку, а не на весь бандл.

Розмір результату після gzip виміряно проти того самого вже мініфікованого файлу, на п'яти реальних мініфікованих продакшн-бандлах, з AfterPack 0.2.6, 16 жовтня 2026 року; метод описано на сторінці Продуктивність.

Мінімальне кодування рядків увімкнене для будь-якого додатного цільового значення.

Ціна завантаження

Виміряно з AfterPack 1.0.0, 24 жовтня 2026 року, на п'яти малих застосунках, зібраних на Vite і React, Vue, Astro, SvelteKit і Next.js. Кожен застосунок запускався з усім бандлом на одному пресеті й порівнюється з тим самим застосунком, зібраним без AfterPack; метод і час для кожного застосунку наведено на сторінці Продуктивність.

ПресетJavaScript, який завантажує сторінка, без стисненняЧас до першого робочого кліку
light1.12x–1.42x+4 ms–+32 ms
medium10.2x–11.9x3.1x–11x
hard14.3x–15.8x3.2x–13.7x
extreme27.1x–30.7x5.9x–24x

Розмір зростає приблизно в стільки ж разів на кожному фреймворку. Час запуску зростає залежно від того, скільки цього коду виконується, перш ніж сторінка почне реагувати, тому застосунок на Next.js заплатив найбільше. Власний рантайм фреймворку є частиною бандла, і кожен пресет захищає також його.

На всьому бандлі застосунку light додає щонайбільше десятки мілісекунд. Починаючи з medium, виміряйте власні сторінки, перш ніж випускати пресет на весь бандл.

За замовчуванням діє light

Запустіть npx afterpack@latest dist/ без --preset або встановіть плагін і нічого не налаштовуйте, і ви отримаєте light.

$ npx afterpack@latest dist/
npx afterpack@latest dist/ --preset=hard    # step up

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

light є базовим рівнем без конфігурації. Кожен рядковий літерал, який він може переписати, проходить через декодер під час виконання. Він перейменовує ідентифікатори й переписує синтаксис, а структурних шарів не додає. Починаючи з рушія 0.2.3, на minify і light цикли більше не переписуються в допоміжні функції зі зворотним викликом, що усуває сповільнення у 2-5 разів, яке ці функції спричиняли в гарячих циклах. На light імена властивостей і глобальні імена й далі проходять через закодовані константи, що має певну ціну в дуже гарячому коді. Деякі рядки залишаються читабельними на будь-якому пресеті: прологи директив, операнди порівняння з typeof, імена властивостей, потрібні рантайму, та імена експортів. Protection Map перелічує їх, а рушій повідомляє їхню кількість і сумарний розмір у байтах на кожній збірці. Підвищення пресету до medium або вище додає структурну роботу над кожним токеном: роздування, перебудову потоку керування, а також прив'язку рядків і цілих чисел до спільного значення під час виконання. Читабельність рядків воно не змінює: вона вже на своєму мінімумі.

minify є єдиним рівнем, який вимикає це мінімальне кодування. Починаючи з рушія 0.2.3, він лише перейменовує ідентифікатори й стискає код, без жодної обфускації. Рушій 0.2.2 на minify також переписував синтаксис.

Бюджет розміру

Кожен результат містить фіксований рантайм рушія (декодери та інтерпретатор цілочислових виразів), тож файл на кілька сотень байтів виходить пропорційно більшим, ніж передбачають ці діапазони. Читайте співвідношення на реальному бандлі, а не на маленькому файлі.

inflation.max незаданий за замовчуванням, тож цільова складність сама вирішує розмір результату. Задавайте його самостійно лише тоді, коли у вас є реальний бюджет розміру, який краще не перевищити. Досягнення явно заданого значення є помилкою: DIAG_SIZE_CAP_REACHED, без результату, код виходу 3 з CLI, а в плагіні збірка завершується з помилкою. Починаючи з рушія 0.2.3, недостатньо захищений результат ніколи не записується замість нього: із лімітом звіряється готовий файл, а кодування рядків завжди завершується першим. У рушії 0.2.2 тісний ліміт міг перервати кодування рядків і залишити частину рядків читабельними.

Обфусковані байти, а отже й розмір після gzip, змінюються від збірки до збірки за задумом. Типово кожна збірка отримує новий сід, а seed: "git" отримує новий з кожним комітом, тож кожен реліз постачає іншу програму. Фіксований сід відтворює ті самі байти лише для того самого входу на тій самій версії рушія. Задавайте бюджет розміру бандла для коду в тому вигляді, як його записав бандлер, до AfterPack, або давайте бюджету для захищеного результату запас.

Пряме задання цільового значення

complexity є необмеженим невід'ємним числом. --complexity=200 є допустимим перевизначенням на тарифі Free, далеко за межами того, що задає extreme.

npx afterpack@latest dist/ --preset=hard --complexity=40

Це hard із цільовою складністю, перевизначеною на 40; решта пресету не змінюється. Передати назву пресету в --complexity є помилкою.

Застосування пресету до однієї ділянки

На Free один пресет охоплює всю збірку: --preset у CLI або preset у вашій конфігурації. Єдиний вужчий засіб керування — paths.exclude, який повністю виключає файли й копіює їх у результат без захисту. Кожен інший файл платить ціну завантаження пресету, тож тримайте весь бандл застосунку на light, якщо ваші власні вимірювання не дозволяють більшого.

На Pro директива у вихідному коді застосовує важчий пресет до однієї функції чи файлу, а решта бандла зберігає ваш глобальний пресет:

/* @afterpack preset=extreme */
function pricingEngine(plan, region) {
  return resolve(plan, region);
}
/* @afterpack end */

Щоб охопити файл, загорніть його код в одну директиву. Директиви пишуться лише як блокові коментарі і зчитуються з вашого вихідного коду плагіном фреймворку; CLI їх не зчитує. Граматику та правила тарифів див. у Директивах.

Далі