@afterpack/webpack — це плагін для webpack 5: клас з apply(compiler). Він зчитує директиви @afterpack з вашого вихідного коду до мініфікації, а потім запускає рушій на compilation.hooks.processAssets одразу після того, як webpack призначає імена з хешем вмісту, і до запису.
Байти кожного ассета зчитуються з компіляції, а обфускована заміна передається назад у неї, тож webpack ніколи не записує ваш необфускований бандл. Невдала обфускація залишає каталог виводу таким, яким він був.
Встановлення
$ npm install -D @afterpack/webpack// webpack.config.js
import { AfterpackWebpackPlugin } from "@afterpack/webpack";
export default {
mode: "production",
output: { path: "dist" },
plugins: [new AfterpackWebpackPlugin()],
};Експорт — це клас AfterpackWebpackPlugin.
Збірка
Плагін під'єднується до compilation.hooks.processAssets одразу після етапу, на якому webpack обчислює хеші вмісту. Ім'я кожного чанка слідує за його обфускованими байтами. Переписуються лише ассети .js, .mjs і .cjs, які належать якомусь чанку компіляції; чанки .hot-update. пропускаються. Ассет, який компілятор містить, але не збирав, наприклад маніфест, згенерований іншим плагіном, або скопійований файл, лишається без змін.
Плагіни стиснення запускаються на пізнішому етапі, тож стискають уже обфусковані байти.
processAssets запускається на кожній компіляції, зокрема на перезбірках у watch-режимі, і кожна перезбірка платить ціну роботи рушія. Задайте build.autorun: false (або AFTERPACK_build_autorun=false) для циклу розробки і залиште його увімкненим для продакшн-збірок.
Перевірка
Protection Map за замовчуванням записується, коли devtool створює source map і збірка не працює в CI (CI=true або CI=1); продакшн-режим збірки її не вимикає. Продакшн-збірка webpack за замовчуванням не має devtool, тож мапа вимкнена. Запросіть її явно:
new AfterpackWebpackPlugin({ protectionMap: { enabled: true } });Значення мапи за замовчуванням залежить від наявності source map бандлера, тож задайте devtool: "source-map", якщо хочете, щоб вона показувала ваш оригінальний вихідний код. Без нього плагін попередить, що не знайшов source map бандлера. Якщо мапа записується, то у .afterpack/protectionMap.html, внесений у gitignore, і ніколи в dist/. Вона містить увесь ваш вихідний код. Ніколи не комітьте його і не роздавайте з сервера.
entitlements.js, 54 lines, built at the light preset with a directive around the signature check. Click any token to see what was applied to it.Параметри
Будь-який ключ конфігурації можна передати тут в об'єкті параметрів, наприклад new AfterpackWebpackPlugin({ preset: "hard", complexity: 40 }). Назви точно повторюють @afterpack/vite і @afterpack/next, тож конфігурацію можна переносити між пакетами.
Директиви
Директиви — це можливість тарифу Pro. У збірці Free директива, яка посилює захист, зупиняє збірку з помилкою DIAG_PRO_DIRECTIVE_REQUIRES_KEY.
Директиви зчитуються плагіном із вашого вихідного коду.
/* @afterpack preset=hard */
function verifyLicense(token) {
// ...
}
/* @afterpack end */Директиви бувають лише блоковими коментарями: рядковий коментар // @afterpack … не сканується і з'являється як діагностика. Повна граматика — на сторінці Директиви.
Збір директив пропускає node_modules і модулі, що не є JS/TS. Задайте directives.enabled: false, щоб повністю пропустити сканування; написані вручну regions працюють у будь-якому разі.
Особливі випадки
- Сторонній код у бандлі. webpack об'єднує
node_modulesз вашими чанками, тож немає шаблону імен вихідних файлів, який би їх розділяв. AfterPack працює зі згенерованими файлами цілком;paths.exclude— це виключення на рівні файлів, коли воно вам потрібне. webpack-subresource-integrityвідхиляється. Його атрибутиintegrityне збігалися б з обфускованими чанками. Приберіть його й обчисліть цілісність за згенерованими файлами після збірки.- Зупинка з помилкою (fail closed), без можливості перевизначення. Невдалий файл або порожній результат завершують збірку помилкою, а не випускають необфускований код.
Далі
- Фреймворки: повна матриця.
- Vite: еталонна інтеграція і повна семантика параметрів.
- Конфігурація: кожен параметр вище і де його можна задати.
- Директиви: повна граматика маркерів.
- Пресети: шкала, за якою визначається
preset. - Збірки та CI: сіди, dev проти prod, просування тих самих байтів.
- Protection Map: як читати звіт.