# Обфускація збірки esbuild

@afterpack/esbuild підключається до build.onEnd і обфускує виданий результат на місці.

Source: https://www.afterpack.dev/uk/docs/frameworks/esbuild

`@afterpack/esbuild` є стандартним плагіном esbuild (`{ name, setup(build) }`). Він підключається до `build.onEnd`, який спрацьовує, щойно esbuild закінчив записувати результат на диск (`write !== false`, значення за замовчуванням).

Він підтримує обидві форми виводу: `outdir` (багато файлів) і `outfile` (один файл). Збірку, яка вже завершилася помилкою, він пропускає.

## Встановлення

```bash
npm install -D @afterpack/esbuild
```

```js
// build.mjs
import { build } from "esbuild";
import { afterpackEsbuild } from "@afterpack/esbuild";

await build({
  entryPoints: ["src/main.js"],
  bundle: true,
  format: "esm",
  outfile: "dist/app.js",
  plugins: [afterpackEsbuild()],
});
```

Іменований експорт: `afterpackEsbuild`.

## Збірка

Плагін запускається на `build.onEnd`, після того як esbuild закінчив записувати результат на диск, однаково для `outdir` і `outfile`. Окремої dev-команди, яку він міг би пропускати, немає: кожен виклик `build()`, що записує файли, запускає плагін.

esbuild не надає хука всередині конвеєра, тож ваш необфускований бандл лежить на диску, доки прохід не завершиться, а для бандла на 185 KB на пресеті за замовчуванням це триває приблизно чверть секунди, і все, що може читати каталог виводу в цей проміжок, може його прочитати. Невдала обфускація залишає цей результат на місці: збірка завершується помилкою, тож у реліз нічого не потрапляє, але файли лишаються, доки наступна збірка їх не перезапише.

## Перевірка

[Protection Map](https://www.afterpack.dev/uk/docs/protection-map) за замовчуванням записується, коли esbuild видає [source map](https://www.afterpack.dev/uk/docs/config#sourceMap-enabled) і збірка не працює в CI (`CI=true` або `CI=1`); [продакшн-режим](https://www.afterpack.dev/uk/docs/config#build-mode) її не вимикає. esbuild не видає source map, якщо ви не задали `sourcemap`, тож мапа за замовчуванням вимкнена. Запитайте її явно:

```js
afterpackEsbuild({ protectionMap: { enabled: true } });
```

Вона записується в `.afterpack/protectionMap.html`, внесений у gitignore. Без `sourcemap: true` плагін попереджає, що не знайшов мапи бандлера, з якої можна відобразити оригінальний вихідний код. Звіт містить увесь ваш вихідний код. Ніколи не комітьте його і не роздавайте з сервера.

## Параметри

Будь-який [ключ конфігурації](https://www.afterpack.dev/uk/docs/config) можна передати тут в об'єкті параметрів, наприклад `afterpackEsbuild({ preset: "hard", complexity: 40 })`.

## Директиви

Директиви відновлюються із source map бандлера, тож якщо ви їх використовуєте, збирайте з `sourcemap: true`. Див. [Директиви](https://www.afterpack.dev/uk/docs/directives).

## Особливі випадки

- **[Зупинка з помилкою (fail closed)](https://www.afterpack.dev/uk/docs/diagnostics#fail-closed-no-exceptions).** Невдалий файл або порожній результат відхиляє збірку.
- **`write: false`.** На диску нічого немає, тож плагін нічого не робить. AfterPack потрібні записані файли.
- **TypeScript.** На момент запуску AfterPack esbuild уже прибрав типи; мапи ведуть назад до рядків вашого `.ts`.

## Далі

- [Фреймворки](https://www.afterpack.dev/uk/docs/frameworks): повна матриця.
- [Vite](https://www.afterpack.dev/uk/docs/frameworks/vite): еталонна інтеграція і повна семантика параметрів.
- [Збірки та CI](https://www.afterpack.dev/uk/docs/builds): сіди, dev проти prod, просування тих самих байтів.
- [Protection Map](https://www.afterpack.dev/uk/docs/protection-map): як читати звіт.
- [Директиви](https://www.afterpack.dev/uk/docs/directives): кожен ключ позначки і що він робить.
- [Конфігурація](https://www.afterpack.dev/uk/docs/config): поверхня конфігурації рушія.
