AfterPack працює з Cloudflare Worker двома способами, через той самий пакет і той самий виклик. Без ключа рушій Free працює всередині вашого Worker як модуль WebAssembly, який ви встановлюєте з npm. З вашим ключем Pro збірка виконується в хмарі AfterPack на рушії Pro.
Ця сторінка описує обидва способи, а потім показує, як кешувати результат, щоб кожен ассет збирався один раз на вікно ротації.
AfterPack у вашому власному Worker
@afterpack/wasm — це AfterPack, скомпільований у WebAssembly. Це той самий рушій на Rust, який запускають CLI і плагіни для фреймворків, зібраний для wasm32, а не для архітектури вашої машини.
npm install @afterpack/wasmimport { obfuscate } from "@afterpack/wasm";
export default {
async fetch(request) {
const source = await request.text();
const result = await obfuscate({ path: "app.js", source }, { preset: "hard" });
return new Response(result.bytes, {
headers: { "content-type": "application/javascript" },
});
},
};Це вся інтеграція. Ні виклику init, ні прапорця nodejs_compat, ні правила wrangler для файлу .wasm. Модуль не має імпортів WebAssembly, тож він синхронно інстанціюється під час першого виклику obfuscate, а мапа exports пакета сама віддає вашому бандлеру точку входу, придатну для Worker. Той самий імпорт працює в Node, де інша точка входу зчитує бінарний файл із диска.
Інтерфейс ідентичний @afterpack/core: obfuscate, obfuscateAll, version, усі асинхронні й усі кидають виняток на збірці, яку не можна випустити. Конфігурація — той самий об'єкт, описаний на сторінці Конфігурація, зокрема preset і seed.
@afterpack/core постачає нативний бінарний файл і працює швидше. Беріть @afterpack/wasm, коли хост не може його завантажити: Worker, ізольований образ CI, edge-функція.
Скільки це коштує
Бінарний файл рушія постачається всередині пакета, уже скомпільований.
| Байти | Розмір | |
|---|---|---|
Сирий .wasm | 4,573,321 | 4.36 MiB |
| Після gzip | 1,307,772 | 1.25 MiB |
Ліміт розміру Worker у Cloudflare — 3 MB у стисненому вигляді на безкоштовному плані і 10 MB на платному, тож рушій вміщується в обидва. Що не вміщується в безкоштовний план, так це робота: він обмежує CPU до 10 ms на виклик, а обфускація бандла на 185 KB на ядрі ноутбука займає менш ніж 0.3 секунди на пресеті за замовчуванням light і приблизно 1 секунду на medium. Усьому, що виходить за межі демо, потрібен Workers Paid.
Worker, який обфускує той самий ассет на кожен запит, щоразу платить за цей CPU. Кешування результату на вікно ротації або виконання цієї роботи у вашій збірці з подальшою роздачею результату тримає рахунок низьким там, де нова форма на кожен запит вам не потрібна.
Що може і чого не може пакет, який ви хостите
.wasm, який ви встановлюєте, виконує захист рівня Free. Трансформації Pro працюють лише на інфраструктурі AfterPack, тож у пакеті немає нічого, що можна розблокувати: ні перевірки ключа, яку можна обійти, ні перемикача, що перетворює розміщену у вас копію на збірку Pro. key спрямовує роботу в хмару; локально він нічого не вмикає.
Опублікований пакет має запис npm provenance — версію пакета, workflow, який його зібрав, і дайджест артефакту, — тож ви можете пов'язати встановлені байти зі збіркою, яка їх створила.
Pro з вашого власного Worker
Передайте свій key у конфігурації того самого виклику obfuscate(), наприклад із секрету Worker, і збірка виконається в хмарі AfterPack на рушії Pro:
import { obfuscate } from "@afterpack/wasm";
export default {
async fetch(request, env) {
const source = await request.text();
const result = await obfuscate(
{ path: "app.js", source },
{ preset: "hard", key: env.AFTERPACK_KEY },
);
return new Response(result.bytes, {
headers: { "content-type": "application/javascript" },
});
},
};Пакет сам надсилає запит на POST /v1/obfuscate/batch, тож Worker ніколи не програмує API вручну. Файли, завеликі для Worker, автоматично переходять у контейнери. Рушій Pro ніколи не потрапляє у ваш Worker: він працює лише на інфраструктурі AfterPack, і саме це є межею між тарифами, описаною вище.
Кожен виклик є тарифікованою збіркою Pro (скільки коштує Pro) плюс швидким запитом усередині мережі Cloudflare. Можна збирати на кожен запит, але кожна збірка оплачується, тож краще кешуйте результат на вікно ротації.
Ваш вихідний код залишає ваш Worker і обробляється в хмарі AfterPack, у пам'яті й без збереження, згідно з Конфіденційністю і обробкою даних. Виклик зупиняється з помилкою (fail closed), якщо хмара недоступна: він кидає виняток, і нічого незахищеного не публікується. Довідник Cloud API містить повний контракт протоколу, а Режими розгортання пояснюють, що змінюється, коли рушій переїжджає.
Пакет, який стверджує, що виконує трансформації Pro на вашій власній інфраструктурі, не наш. Перевірте запис npm provenance, перш ніж встановлювати будь-що під цією назвою.
Кешуйте результат на вікно ротації
Виводьте seed з поточного часового вікна і кешуйте результат під ключем, що містить це вікно. Тоді кожна локація збирає ассет один раз на вікно й віддає його до кінця вікна, і на Free, і на Pro:
import { obfuscate } from "@afterpack/wasm";
import source from "./pricing.client.js";
const WINDOW_SECONDS = 600;
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
if (url.pathname !== "/pricing.js") {
return new Response("Not found", { status: 404 });
}
const now = Math.floor(Date.now() / 1000);
const slot = Math.floor(now / WINDOW_SECONDS);
const secondsLeft = (slot + 1) * WINDOW_SECONDS - now;
const cacheKey = new Request(`${url.origin}/pricing.js?slot=${slot}`);
let response = await caches.default.match(cacheKey);
if (!response) {
const result = await obfuscate(
{ path: "pricing.js", source },
{ preset: "hard", seed: `pricing.js:${slot}`, key: env.AFTERPACK_KEY },
);
response = new Response(result.bytes, {
headers: {
"content-type": "application/javascript",
"cache-control": `public, max-age=${secondsLeft}`,
},
});
ctx.waitUntil(caches.default.put(cacheKey, response.clone()));
}
response = new Response(response.body, response);
response.headers.set("cache-control", `public, max-age=${secondsLeft}`);
return response;
},
};Без секрету AFTERPACK_KEY значення key дорівнює undefined, і той самий Worker збирає на Free всередині вашого Worker. Вихідний файл імпортується як рядок через правило wrangler Text, як у повному розборі.
Вікно є і в seed, і в ключі кешу, тож кожна локація з тим самим розгортанням віддає ті самі байти протягом вікна, а нове вікно ніколи не читає старий запис. Вихідний cache-control веде відлік до кінця вікна, тож браузер ніколи не тримає копію довше. Cache API зберігає записи окремо в кожному дата-центрі й не працює в редакторі дашборду, тож тестуйте через wrangler dev або на розгорнутому маршруті.
Вибір
| Вам потрібно | Використовуйте |
|---|---|
| Обфускація у Worker, нічого не залишає ваш обліковий запис | @afterpack/wasm, ця сторінка |
| Обфускація у звичайній збірці на Node | @afterpack/core або CLI |
| Посилений захист Pro і директиви для окремих ділянок, з Worker | Той самий виклик із key, який збирає в хмарі AfterPack |
| Нова форма на кожне вікно без збірки на кожного відвідувача | Кеш на вікно ротації |
Далі
- Режими розгортання: локальний режим проти хмарного і що зберігає кожен із них.
- Довідник Cloud API: контракт, який викликає Worker для збірок Pro.
- Конфігурація: кожен ключ, який приймають обидва пакети.
- Тарифи: що входить у Free і що додає Pro.
- Конфіденційність і обробка даних: що залишає ваш комп'ютер у кожному режимі.