AfterPack ніколи не випускає слабший захист, ніж ви запитали. Коли щось не вдається розв'язати автоматично, збірка зупиняється з іменованим кодом DIAG_* і конкретним способом виправлення.
Рівні серйозності
Кожна діагностика, яку видає AfterPack, має рівно один із трьох рівнів серйозності. Рівня Warning немає.
| Рівень | Значення | Що відбувається |
|---|---|---|
| Info | Очікувана поведінка: ви вже це підтвердили, або рушій обрав безпечний запасний варіант, що зберігає коректність. | Збірка успішна, результат записано. |
| Error | Ваші вимоги неможливо виконати без змін з вашого боку (занадто жорстке обмеження розміру, помилка розбору, недійсний ключ). | Ненульовий код виходу, результат не записано. |
| Critical | Помилка рушія. Жодні ваші дії цього не виправлять. | Ненульовий код виходу, результат не записано, завжди. Надішліть звіт. |
Коди виходу
npx afterpack@latest повертає один із восьми кодів. Пишіть скрипти безпосередньо під них.
| Код | Значення |
|---|---|
0 | Успіх. Кожен зібраний файл обфусковано і записано. --help і --version також завершуються з кодом 0. |
1 | Помилка. Нічого придатного не створено, а повідомлення в stderr називає, що сталося. |
2 | Частково. Зарезервовано для збірки з вичерпаною квотою; сьогодні жодна збірка його не повертає. |
3 | Обмеження розміру. Результат досяг би заданого вами inflation.max (DIAG_SIZE_CAP_REACHED). |
4 | Потрібен Pro. Запис regions підвищує захист понад конфігурацію програми й потребує key (DIAG_PRO_DIRECTIVE_REQUIRES_KEY). CLI не читає директив із вихідного коду, тож до цього виходу веде лише regions. |
5 | Рефлексія. Виявлено патерн рефлексії під час виконання без reflection.allow (DIAG_REFLECTION_NOT_ACKNOWLEDGED). |
6 | Потрібне оновлення. Хмарі AfterPack або цьому afterpack потрібен новіший @afterpack/core. Нічого не записано. |
64 | Неправильне використання. Невідомий прапорець або команда, некоректне значення або продубльований аргумент шляху. |
Коли збірка завершується з кодом 64
Проблеми використання зупиняють запуск ще до його початку.
- Невідомий прапорець, невідома команда, некоректне значення або більше ніж один позиційний шлях. Рядок використання друкується повторно разом із помилкою.
Коли збірка завершується з кодом 1
- Немає аргументу
<path>і не знайдено результату збірки (dist/,build/,out/,.output/,.next/або каталог, у який за домовленістю пише бандлер, названий уpackage.json). AfterPack ніколи не читає власний файл конфігурації бандлера, тож нестандартний каталог виводу таким чином не визначається. - Каталог збірки не існує або не містить файлів
.js/.mjs/.cjs. Порожній каталог збірки завершує збірку помилкою. Зазвичай причина в тому, що вказано не той каталог або запуск відбувся до збірки. - Файл повністю не вдалося обробити, або для непорожнього входу повернувся порожній результат.
- Файл, який рушій не може безпечно обфускувати. Збірка завершується помилкою і називає відповідні файли. Використовуйте
paths.exclude, щоб виділити файл, який має вийти незмінним. - Невдалий
verifyабо невдале скануванняaudit. - Будь-який код нижче з рівнем серйозності
ErrorабоCritical, крімDIAG_SIZE_CAP_REACHED(вихід3),DIAG_PRO_DIRECTIVE_REQUIRES_KEY(вихід4) іDIAG_REFLECTION_NOT_ACKNOWLEDGED(вихід5).
Зупинка з помилкою (fail closed), без винятків
Збірка Pro або випускає захист рівня Pro, або не випускає нічого.
Щойно визначено key, з AFTERPACK_key або з afterpack.json, збірка стає хмарною. Якщо хмарний виклик не вдався з будь-якої причини, рушій повертає помилку, і збірка завершується з кодом 1, або 6, коли хмарі потрібен новіший @afterpack/core. Вона не повертається до локальної збірки і не видає необфускований результат. Прапорця, який випускав би необфускований результат, немає. Зупинка збірки виносить проблему туди, де ви її побачите.
Цей контракт не залежить від способу виклику: npx afterpack@latest і автозапуск плагіна після закриття бандла поводяться однаково.
Коди виходу в CI
npx afterpack@latest dist/ || {
echo "AfterPack failed: nothing shipped. See the error above."
exit 1
}Ненульовий код зупиняє пайплайн. Причина з'являється в stderr і в кодах нижче.
Повний довідник
Рушій
| Код | Значення |
|---|---|
DIAG_TARGET_REACHED | Info. Кожна частина файлу досягла запитаної complexity. |
DIAG_TARGET_NOT_REACHED | Починаючи з рушія 0.2.3, Error, і результат не записується: частина файлу не може досягти цільової complexity з дозволеними вами трансформаціями, бо transforms.scopeDeepen.enabled має значення false або директива ділянки обмежує ці рядки. Повідомлення називає файл і рядки. Увімкніть трансформацію знову, знизьте complexity для цього файлу чи ділянки або виключіть файл через paths.exclude. У рушії 0.2.2 це був Info: збірка постачала менш глибокий результат, а недобір через вимкнену трансформацію міг повідомлятися як DIAG_TARGET_REACHED. |
DIAG_INFLATION_BUDGET_HIT | Info. Лише на збірці без floor зі скінченним inflation.max: етап, що додає розмір, зупинився на цьому бюджеті, не досягнувши цілі. Результат коректний. Починаючи з рушія 0.2.3, floor рядкових констант ніколи не поступається бюджету, тож на збірці з floor цей код ніколи не з’являється і не означає, що рядковий літерал залишився читабельним. У рушії 0.2.2 явно заданий inflation.max міг перервати й кодування рядків; якщо ви його задавали, перезберіть проєкт на рушії 0.2.3. |
DIAG_SIZE_CAP_REACHED | Error, код виходу 3, і результат не записується: результат досяг би заданого вами inflation.max. Починаючи з рушія 0.2.3, із цим лімітом звіряється й готовий файл, повідомлення називає обидва розміри в байтах, а кодування рядків ніколи не переривається, щоб вкластися в ліміт. Підвищте inflation.max, знизьте complexity або виключіть файл через paths.exclude. |
DIAG_SELF_INTEGRITY_INERT | Error, починаючи з рушія 0.2.3, лише Pro, і результат не записується: transforms.selfIntegrity.enabled увімкнено, але в збірці немає коду рівня medium або вище з увімкненим transforms.crossDependency.enabled, до якого можна прикріпити перевірку. Підніміть пресет або ділянку до medium, знову увімкніть crossDependency або вимкніть selfIntegrity. У рушії 0.2.2 така збірка завершувалася успішно без перевірки цілісності. |
DIAG_PATH_EXCLUDED | Info. Файл відповів paths.exclude і вийшов побайтово незмінним; його байти враховано як виключені користувачем. |
DIAG_DYNAMIC_SCOPE_NATIVE | Info, починаючи з рушія 0.2.3. Інструкція with або прямий eval залишили області видимості навколо себе такими, як написано: імена в кожній охопній області видимості, аж до верхнього рівня файлу, зберігають оригінальне написання, а глобальні змінні всередині тіла with залишаються такими, як написано. Решта файлу обфускується як зазвичай. Щоб захистити ці імена, викликайте eval опосередковано, (0, eval)(code), якщо виконуваному коду не потрібні локальні змінні, або винесіть код, якому потрібен eval чи with, в окремий файл. Див. Семантичний контракт. |
DIAG_SURVIVING_READABLE_LITERAL | Читабельних рядкових літералів залишилося більше, ніж дозволяє strings.leaks.max. Підвищте complexity, знизьте strings.minLength або підвищте ліміт. |
DIAG_SOURCE_MAP_INTEGRITY | Info. Наданий вхідний .map не пройшов перевірку щодо свого входу, тож карту цього файлу відкидають, а обфускований код усе одно виходить. Відсутня карта нешкідлива; шкода, якої це уникає, — віддати хибну. |
DIAG_OUTPUT_UNPARSEABLE | Error, і ознака помилки рушія. Повторний розбір результату не вдався, тож для цього файлу збірка завершується безпечно (fail closed): без коду, без карти джерел, без Protection Map. |
DIAG_PARSE_ERROR | Error. Вхідний чанк не розібрався. AfterPack працює строго після збірки, на згенерованому JavaScript: спочатку скомпілюйте, потім вкажіть йому на JS-результат. |
DIAG_CONFIG_PARSE_ERROR | Error. JSON конфігурації рушія не десеріалізувався. |
DIAG_PRO_DIRECTIVE_REQUIRES_KEY | Error, вихід 4, і результат не записується: збірка Free натрапила на директиву ділянки, яка посилює захист понад конфігурацію програми. Задайте key або приберіть директиву. Починаючи з рушія 0.2.3, директива, яка лише послаблює захист, у Free ігнорується; рушій 0.2.2 відхиляв і таку. |
DIAG_INPUT_TOO_LARGE | Один вхідний файл перевищив обмеження розміру. |
DIAG_BATCH_TOO_LARGE | Пакет понад 500 MB загалом (413, без повторної спроби); збірка зупиняється з помилкою (fail closed). |
DIAG_INPUT_NESTING_EXCEEDS_ENVIRONMENT | Error. Вхідні дані вкладені глибше, ніж парсер може безпечно обробити, — оцінюється ще до парсингу за межею 160 рівнів. Результат не записується. Зменшіть вкладеність вихідного коду. |
DIAG_OUTPUT_NESTING_EXCEEDS_ENVIRONMENT | Error. Обфускований результат вкладався б глибше 400 рівнів — межі, яку браузери та Workers можуть безпечно розібрати. Результат не записується. Знизьте complexity для цього входу. |
DIAG_ENGINE_BUG_NO_PROGRESS | Critical. Рушій не просунувся. Це помилка рушія. |
DIAG_ENGINE_BUG_NO_APPLICABLE_TRANSFORM | Critical. Частина файлу залишилася нижче цільової складності, і жодна вимкнена трансформація чи директива ділянки цього не пояснює. Це помилка рушія. |
DIAG_ENGINE_BUG_PROCESS_THREAD_PANIC | Critical. Робочий потік запанікував. Це помилка рушія. |
Плагін збірки / CLI
| Код | Значення |
|---|---|
DIAG_DIRECTIVE_UNKNOWN | Директива @afterpack назвала нерозпізнаний ключ. Звірте його з тим, які ключі може перевизначати ділянка. |
DIAG_DIRECTIVE_UNSUPPORTED_FORM | Цю форму маркера неможливо розмістити (рядковий коментар // @afterpack … або діапазон @afterpack:begin/:end). Використовуйте блокові маркери /* @afterpack … */. |
DIAG_DIRECTIVE_NOT_IMPLEMENTED | У директиві записано ключ рівня всієї програми (наприклад, reflection.allow) або надлишкову директиву на кшталт skip=false. Що насправді може перевизначати ділянка, див. у розділі Які ключі. |
DIAG_DIRECTIVE_SOURCE_UNRESOLVED | Info. Директива стоїть у модулі, чию позицію не вдалося зіставити з результатом збірки, тож її не застосовано. Перенесіть позначений код в імпортований модуль. |
DIAG_DIRECTIVE_DANGLING_END | /* @afterpack end */ без відкритого блоку над ним. |
DIAG_DIRECTIVE_REGION_TO_FILE | identifiers.globals.rename не можна обмежити ділянкою, тож директиву, яка його називає, проігноровано, і про це повідомлено. |
DIAG_DIRECTIVE_COVERAGE_UNVERIFIED | Бандлований чанк із директивами не мав source map, який можна декодувати, тож позначені ділянки не вдалося знайти в його байтах. |
DIAG_DIRECTIVE_TARGET_ELIMINATED | Директиви знайдено в map чанка, але вони не відповіли жодному діапазону. Позначений код видалено tree-shaking, або координати не збіглися. |
DIAG_ALREADY_OBFUSCATED | Зібрані файли вже містять власний обфускований результат AfterPack від попереднього запуску, що встановлено зіставленням із квитанцією захисту за хешем вмісту. Результат AfterPack не ідемпотентний: спочатку перезберіть із вихідного коду. |
DIAG_AFTERPACK_DIR_IN_OUTPUT | Помилка, і нічого не перезаписано. Усередині результату збірки є папка .afterpack/, де її резервні копії, квитанції та Protection Map потрапили б у розгортання. Видаліть її і зберіть знову. Див. де лежить .afterpack/. |
DIAG_RECEIPT_UNWRITABLE | Помилка, і нічого не перезаписано. Квитанцію захисту не вдається записати в .afterpack/receipts/. Зробіть цю папку доступною для запису і зберіть знову. |
Хмарний API
| Код | Значення |
|---|---|
DIAG_INVALID_KEY | Відсутній, некоректний або невідомий key (401). Перевірте AFTERPACK_key або випустіть новий ключ у дашборді. |
DIAG_KEY_REVOKED | API-ключ відкликано (401). |
DIAG_KEY_EXPIRED | Термін дії API-ключа минув (401). |
DIAG_KEY_OUT_OF_SCOPE | IP запиту поза дозволеним для ключа діапазоном (403). |
DIAG_MISSING_IP | Запит не містив IP клієнта (400). |
DIAG_INVALID_MANIFEST | Некоректне multipart-тіло або відсутня частина з маніфестом batch. |
DIAG_FILE_TOO_LARGE | Один файл перевищив обмеження в байтах на файл (413). Розділіть його або виключіть через paths.exclude. |
DIAG_ENTITLEMENT_LAPSED | Оплату підписки прострочено (402); оновіть платіжні дані, щоб і далі збирати. |
DIAG_QUOTA_EXHAUSTED | Загальний обсяг байтів збірки перевищує залишок ліміту, або досягнуто ліміту витрат на перевищення. Перевіряється один раз на збірку, до відправлення будь-якого файлу, тож нічого вже захищеного не погіршується. Поповніть баланс, перейдіть на вищий тариф або підвищте ліміт; помилка містить посилання. |
DIAG_RATE_LIMITED | Перевищено ліміт частоти запитів (429); дотримуйтеся Retry-After. |
DIAG_RATE_CHECK_UNAVAILABLE | Сама перевірка ліміту частоти не вдалася, тож запит зупиняється з помилкою (fail closed) (503); повторіть спробу. |
DIAG_BUILD_DEADLINE | Бюджет реального часу вичерпався до того, як почалася обробка кожного файлу; незавершені файли названо. |
DIAG_ENGINE_FAILURE | Хмарний рушій зазнав збою на файлі. |
Рефлексія під час виконання
AfterPack виявляє такі шаблони рефлексії під час виконання: functionToString, nameIntrospection, argumentsCallee, prototypeChain, decoratorMetadata і constructorIntrospection. Кожне виявлення має код: підтверджена форма називає шаблон у коді, непідтверджена — це єдиний DIAG_REFLECTION_NOT_ACKNOWLEDGED, назву шаблону наведено в його повідомленні.
| Код | Значення |
|---|---|
DIAG_REFLECTION_nameIntrospection_ACKNOWLEDGED | Info. Шаблон виявлено і збережено, бо ви його підтвердили. Один код на шаблон; назва посередині є будь-яким із наведених вище шаблонів. |
DIAG_REFLECTION_NOT_ACKNOWLEDGED | Error, вихід 5. Патерн рефлексії виявлено, і його не підтверджено, тож збірка зупиняється замість того, щоб випустити код, чиє читання під час виконання зламалося б; повідомлення називає патерн. Підтвердьте його через reflection.allow, який також приймає angular і nestjs, або виключіть файл через paths.exclude. |
Випадковий .map або необфускований сусідній файл, що потрапив у дерево розгортання, виявляє npx afterpack@latest audit, а не збірка.
Якщо код відсутній або описаний неправильно, створіть issue: github.com/afterpack-dev/afterpack/issues.
Запустіть із --diagnostics.level=all, щоб отримати повний потік діагностики для будь-якої збірки замість стандартного підсумку. У збірці через плагін той самий перемикач є параметром diagnostics.level або AFTERPACK_diagnostics_level.
Далі
- Довідник CLI: кожен прапорець, на який посилаються наведені вище коди.
- Конфігурація: ключі конфігурації, на які посилаються ці коди.
- Семантичний контракт: що результат зберігає незмінним і кілька навмисних відмінностей.
- Директиви: повна граматика
@afterpack, що стоїть за наведеними вище кодами директив. - Найкращі практики: шаблони, що допомагають узагалі уникнути цих діагностик.
- Тарифи: що є у Free, а що потребує
key.