@afterpack/parcel-optimizer — це Optimizer для Parcel 2, зареєстрований у .parcelrc. Він обфускує кожен запакований бандл у пам'яті, під час власної фази оптимізації Parcel, тож бандл ніколи не потрапляє на диск у відкритому вигляді.
Пакет називається @afterpack/parcel-optimizer.
Встановлення
$ npm install -D @afterpack/parcel-optimizer// .parcelrc
{
"extends": "@parcel/config-default",
"optimizers": {
"*.{js,mjs,cjs}": ["...", "@afterpack/parcel-optimizer"]
}
}Розгортання "..." важливе: воно зберігає стандартні оптимізатори Parcel (@parcel/optimizer-swc) і ставить AfterPack останнім. AfterPack працює після мініфікації. Peer-залежність: Parcel >=2.9.0.
Збірка
Записи в .parcelrc є просто назвами пакетів без вбудованих параметрів, тож параметри беруться з afterpack.json у корені проєкту, єдиного файлу конфігурації, який читає кожна інтеграція AfterPack:
{
"seed": "git",
"preset": "medium"
}Записуються лише артефакти в корені проєкту; поруч із вашими бандлами нічого не з'являється:
- По одному
protectionMap.htmlна бандл, у.afterpack/<bundle>.<id>.protectionMap.html. - Source map, коли його вмикає політика sourceMap. Він повертається в Parcel, а не записується напряму, тож Parcel сам дає йому ім'я і видає його з власним хешем вмісту.
.afterpack/ має власний .gitignore; плагін ніколи не редагує .gitignore вашого проєкту.
Перевірка
Оскільки об'єднаного звіту немає, перевіряйте потрібний бандл напряму: .afterpack/<bundle-name>.<id>.protectionMap.html для кожної точки входу або лінивого чанка, які запакував Parcel. Source map у продакшені вимкнені за замовчуванням; щоб це змінити, задайте "sourceMap": { "enabled": true } в afterpack.json. Кожен звіт містить увесь ваш вихідний код. Ніколи не комітьте його і не роздавайте з сервера.
Щоб перевіряти розгортання, додайте reporter плагіна до команди збірки. Тоді кожна збірка записує квитанцію захисту в .afterpack/receipts/ у корені вашого проєкту, по одній на кожен цільовий каталог виводу (.afterpack/receipts/dist.json для dist). afterpack verify завершується помилкою, коли файл змінився після обфускації або коли квитанції немає:
parcel build index.html --reporter @afterpack/parcel-optimizer/reporter
npx afterpack@latest verify distПараметри
Там можна задати кожен ключ конфігурації, наприклад { "preset": "hard", "complexity": 40 }. protectionMap.enabled залежить від того, чи має бандл source map, а не від режиму збірки, і звіт завжди потрапляє в .afterpack/, внесений у gitignore. Параметра build.backup у цього плагіна немає. Якщо його задати, буде попередження. Явні параметри завжди мають пріоритет над продакшн-значеннями за замовчуванням.
Директиви
Плагін зчитує директиви з вашого вихідного коду. Якщо придатного source map немає, проходу нічого відновлювати, і він про це повідомляє.
Директива в модулі точки входу не відновлюється. Прохід повідомляє DIAG_DIRECTIVE_SOURCE_UNRESOLVED і називає модуль. Директиви в усіх інших модулях, що не є точкою входу, працюють як звичайно, щойно source map увімкнено. Якщо вам потрібна директива в модулі точки входу, перенесіть захищений код в імпортований модуль.
Особливі випадки
Заповнювачі хешу вмісту можуть зламати збірку
Коли хешування вмісту увімкнене (за замовчуванням для parcel build) і ціль не підтримує нативний ESM, заповнювачі хешу вмісту Parcel опиняються всередині обфускованих рядків, і кожен чанк, отриманий розділенням коду, у продакшені віддає 404.
Цей плагін виявляє такий конфлікт і зупиняє збірку з помилкою, замість того щоб її випустити:
AfterPack obfuscated 1 Parcel content-hash placeholder(s) in app.[hash].js (HASH_REF_...).
hint: Run `parcel build --no-content-hash` (chunk URLs stop being content-addressed).
hint: Or set "complexity": 0 in afterpack.json to ship minify-only.Стандартний ESM-результат Parcel це не зачіпає.
Варто знати
- Один прохід на бандл, у робочих процесах. Parcel запускає оптимізатори для кожного бандла окремо, а бандли, запаковані в різних робочих процесах, не можуть мати спільного стану. Бандли, запаковані в одному процесі, мають спільний сід. Щоб закріпити один сід для всіх робочих процесів, задайте
seedявно або експортуйтеAFTERPACK_seed. - Parcel кешує результат оптимізаторів. Перезбірка з прогрітим
.parcel-cacheі незміненими вхідними даними не запускає AfterPack повторно і не змінює незакріплений сід. Очистьте.parcel-cacheдля нового проходу; збірки в CI і так починаються з холодного кешу. - Два нешкідливі попередження. Parcel друкує
ES module dependencies are experimental(кожен пакет AfterPack є ESM) і повідомляє, що плагінcontains non-statically analyzable dependencies(це визначення нативного бінарного файлу рушія під час виконання). Жодне з них не впливає на збірку.
Без плагіна: CLI
Зберіть проєкт Parcel як завжди, а потім вкажіть AfterPack на результат:
$ npx parcel build$ npx afterpack@latest dist/ --preset=medium --seed=gitБез аргументу шляху CLI визначає dist/, типовий каталог виводу Parcel; якщо ваш відрізняється, вкажіть каталог явно. AfterPack обходить каталог, збирає кожен .js/.mjs/.cjs і обфускує їх на місці. Запуск через CLI не має захисту від конфлікту хешу вмісту і створює одну об'єднану protectionMap.html для всього каталогу замість однієї на бандл. Правило fail closed усе одно діє: відсутній каталог збірки, відсутність JS-файлів, діагностика рівня error/critical або файл, який рушій не зміг обфускувати, завершуються з кодом 1.
Далі
- Фреймворки: повна матриця.
- esbuild: ще один плагін, який відновлює директиви із source map після мініфікації.
- Довідник CLI: повний перелік прапорців для резервного шляху.
- Збірки та CI: сіди, dev проти prod, просування тих самих байтів.
- Protection Map: як читати звіт.
- Конфігурація: кожен параметр і через який інтерфейс його можна задати.
- Пресети: драбина з п'яти щаблів.