Діагностика (довідник DIAG_*)

Кожен код DIAG_*, який видає AfterPack, що його спричинило, як це виправити, і коди виходу, які повертає збірка.

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, або не випускає нічого.

AfterPack fail-closed behavior on a Pro buildPro build calls the cloudrequests a cloud-side transformCloud reachableCloud unreachableretrying…Obfuscated output written↻ Retries exhaustedexponential backoff, still down✓ EXIT 0build succeeds✕ EXIT 1loud error, build failsSuccess pathcloud-obfuscated output onlyFail-closed guarantee· no Free-tier fallback· no --allow-degraded· never writes plaintextAfterPack never writes an unprotected file in place of a requested Pro one.

Щойно визначено 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_REACHEDInfo. Кожна частина файлу досягла запитаної 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_HITInfo. Лише на збірці без floor зі скінченним inflation.max: етап, що додає розмір, зупинився на цьому бюджеті, не досягнувши цілі. Результат коректний. Починаючи з рушія 0.2.3, floor рядкових констант ніколи не поступається бюджету, тож на збірці з floor цей код ніколи не з’являється і не означає, що рядковий літерал залишився читабельним. У рушії 0.2.2 явно заданий inflation.max міг перервати й кодування рядків; якщо ви його задавали, перезберіть проєкт на рушії 0.2.3.
DIAG_SIZE_CAP_REACHEDError, код виходу 3, і результат не записується: результат досяг би заданого вами inflation.max. Починаючи з рушія 0.2.3, із цим лімітом звіряється й готовий файл, повідомлення називає обидва розміри в байтах, а кодування рядків ніколи не переривається, щоб вкластися в ліміт. Підвищте inflation.max, знизьте complexity або виключіть файл через paths.exclude.
DIAG_SELF_INTEGRITY_INERTError, починаючи з рушія 0.2.3, лише Pro, і результат не записується: transforms.selfIntegrity.enabled увімкнено, але в збірці немає коду рівня medium або вище з увімкненим transforms.crossDependency.enabled, до якого можна прикріпити перевірку. Підніміть пресет або ділянку до medium, знову увімкніть crossDependency або вимкніть selfIntegrity. У рушії 0.2.2 така збірка завершувалася успішно без перевірки цілісності.
DIAG_PATH_EXCLUDEDInfo. Файл відповів paths.exclude і вийшов побайтово незмінним; його байти враховано як виключені користувачем.
DIAG_DYNAMIC_SCOPE_NATIVEInfo, починаючи з рушія 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_INTEGRITYInfo. Наданий вхідний .map не пройшов перевірку щодо свого входу, тож карту цього файлу відкидають, а обфускований код усе одно виходить. Відсутня карта нешкідлива; шкода, якої це уникає, — віддати хибну.
DIAG_OUTPUT_UNPARSEABLEError, і ознака помилки рушія. Повторний розбір результату не вдався, тож для цього файлу збірка завершується безпечно (fail closed): без коду, без карти джерел, без Protection Map.
DIAG_PARSE_ERRORError. Вхідний чанк не розібрався. AfterPack працює строго після збірки, на згенерованому JavaScript: спочатку скомпілюйте, потім вкажіть йому на JS-результат.
DIAG_CONFIG_PARSE_ERRORError. JSON конфігурації рушія не десеріалізувався.
DIAG_PRO_DIRECTIVE_REQUIRES_KEYError, вихід 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_ENVIRONMENTError. Вхідні дані вкладені глибше, ніж парсер може безпечно обробити, — оцінюється ще до парсингу за межею 160 рівнів. Результат не записується. Зменшіть вкладеність вихідного коду.
DIAG_OUTPUT_NESTING_EXCEEDS_ENVIRONMENTError. Обфускований результат вкладався б глибше 400 рівнів — межі, яку браузери та Workers можуть безпечно розібрати. Результат не записується. Знизьте complexity для цього входу.
DIAG_ENGINE_BUG_NO_PROGRESSCritical. Рушій не просунувся. Це помилка рушія.
DIAG_ENGINE_BUG_NO_APPLICABLE_TRANSFORMCritical. Частина файлу залишилася нижче цільової складності, і жодна вимкнена трансформація чи директива ділянки цього не пояснює. Це помилка рушія.
DIAG_ENGINE_BUG_PROCESS_THREAD_PANICCritical. Робочий потік запанікував. Це помилка рушія.

Плагін збірки / 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_UNRESOLVEDInfo. Директива стоїть у модулі, чию позицію не вдалося зіставити з результатом збірки, тож її не застосовано. Перенесіть позначений код в імпортований модуль.
DIAG_DIRECTIVE_DANGLING_END/* @afterpack end */ без відкритого блоку над ним.
DIAG_DIRECTIVE_REGION_TO_FILEidentifiers.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_REVOKEDAPI-ключ відкликано (401).
DIAG_KEY_EXPIREDТермін дії API-ключа минув (401).
DIAG_KEY_OUT_OF_SCOPEIP запиту поза дозволеним для ключа діапазоном (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_ACKNOWLEDGEDInfo. Шаблон виявлено і збережено, бо ви його підтвердили. Один код на шаблон; назва посередині є будь-яким із наведених вище шаблонів.
DIAG_REFLECTION_NOT_ACKNOWLEDGEDError, вихід 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.