# Ofusca un build de webpack

@afterpack/webpack se engancha a compilation.hooks.processAssets y ofusca tus assets antes de que webpack los escriba.

Source: https://www.afterpack.dev/es/docs/frameworks/webpack

`@afterpack/webpack` es un plugin de webpack 5: una clase con `apply(compiler)`. Lee las [directivas `@afterpack`](https://www.afterpack.dev/es/docs/directives) de tu código fuente antes de la minificación y después ejecuta el motor en `compilation.hooks.processAssets`, justo después de que webpack asigne los nombres con hash de contenido y antes de que escriba.

Los bytes de cada asset se leen de la compilación y el reemplazo ofuscado se le devuelve, así que webpack nunca escribe tu bundle sin ofuscar. Una ofuscación fallida deja el directorio de salida como estaba.

## Instalación

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

```js
// webpack.config.js
import { AfterpackWebpackPlugin } from "@afterpack/webpack";

export default {
  mode: "production",
  output: { path: "dist" },
  plugins: [new AfterpackWebpackPlugin()],
};
```

La exportación es la clase `AfterpackWebpackPlugin`.

## Build

El plugin se engancha a `compilation.hooks.processAssets` justo después de la etapa en la que webpack calcula los hashes de contenido. El nombre de cada chunk [sigue a sus bytes ofuscados](https://www.afterpack.dev/es/docs/builds#file-names-and-caching). Solo se reescriben los assets `.js`, `.mjs` y `.cjs` que reclama algún chunk de la compilación; los chunks `.hot-update.` se omiten. Un asset que el compilador lleva pero no compiló, como un manifiesto que emitió otro plugin o un archivo copiado, se deja tal cual.

Los plugins de compresión se ejecutan en una etapa posterior, así que comprimen los bytes ofuscados.

`processAssets` se ejecuta en cada compilación, incluidas las recompilaciones en modo watch, y cada recompilación paga el coste del motor. Establece [`build.autorun: false`](https://www.afterpack.dev/es/docs/config#build-autorun) (o `AFTERPACK_build_autorun=false`) para el ciclo de desarrollo y mantenlo activado en los builds de producción.

## Verificación

El [Protection Map](https://www.afterpack.dev/es/docs/protection-map) se escribe por defecto cuando `devtool` produce un source map y el build no se ejecuta en CI (`CI=true` o `CI=1`); el [modo de build de producción](https://www.afterpack.dev/es/docs/config#build-mode) no lo desactiva. Un build de producción de webpack no tiene `devtool` por defecto, así que el mapa está desactivado. Pídelo de forma explícita:

```js
new AfterpackWebpackPlugin({ protectionMap: { enabled: true } });
```

El [valor por defecto del mapa](https://www.afterpack.dev/es/docs/config#protectionMap-enabled) depende de que exista un source map del bundler, así que establece `devtool: "source-map"` si quieres que muestre tu código fuente original. Sin él, el plugin avisa de que no encontró ningún source map del bundler. Cuando se escribe, el mapa va a `.afterpack/protectionMap.html`, ignorado por git, nunca dentro de `dist/`. Contiene todo tu código fuente. Nunca lo subas al repositorio ni lo sirvas.

*(live Protection Map demo embed — see https://www.afterpack.dev/protection-map-demo)*

## Opciones

Cualquier [clave de configuración](https://www.afterpack.dev/es/docs/config) se puede pasar aquí en el objeto de opciones, por ejemplo `new AfterpackWebpackPlugin({ preset: "hard", complexity: 40 })`. Los nombres coinciden exactamente con los de [`@afterpack/vite`](https://www.afterpack.dev/es/docs/frameworks/vite#options) y [`@afterpack/next`](https://www.afterpack.dev/es/docs/frameworks/nextjs#options), así que una configuración se puede llevar de un paquete a otro.

## Directivas

Las directivas son una función [Pro](https://www.afterpack.dev/es/docs/pro). En un [build Free](https://www.afterpack.dev/es/docs/directives#free-builds), una directiva que aumenta la protección detiene el build con `DIAG_PRO_DIRECTIVE_REQUIRES_KEY`.

El plugin lee las directivas de tu código fuente.

```js
/* @afterpack preset=hard */
function verifyLicense(token) {
  // ...
}
/* @afterpack end */
```

Las directivas son solo comentarios de bloque: un comentario de línea `// @afterpack …` no se analiza y aparece como un [diagnóstico](https://www.afterpack.dev/es/docs/diagnostics). La gramática completa está en la página de [Directivas](https://www.afterpack.dev/es/docs/directives#writing-one).

La captura omite `node_modules` y los módulos que no son JS/TS. Establece [`directives.enabled: false`](https://www.afterpack.dev/es/docs/config#directives-enabled) para omitir el análisis por completo; las [`regions`](https://www.afterpack.dev/es/docs/config#regions) escritas a mano funcionan en cualquier caso.

## Casos límite

- **Código de terceros.** webpack empaqueta `node_modules` junto con tu código en los mismos chunks, así que no hay ningún patrón de nombre de archivo de salida que los separe. AfterPack trabaja sobre los archivos emitidos en su conjunto; [`paths.exclude`](https://www.afterpack.dev/es/docs/config#paths-exclude) es la exclusión a nivel de archivo cuando la necesites.
- **`webpack-subresource-integrity` se rechaza.** Sus atributos `integrity` no coincidirían con los chunks ofuscados. Elimínalo y calcula la integridad a partir de los archivos emitidos después del build.
- **Falla de forma segura, sin posibilidad de anularlo.** Un archivo fallido o un resultado vacío hace fallar el build en lugar de publicar código sin ofuscar.

## Siguiente

- [Frameworks](https://www.afterpack.dev/es/docs/frameworks): la matriz completa.
- [Vite](https://www.afterpack.dev/es/docs/frameworks/vite): la integración de referencia y la semántica completa de las opciones.
- [Configuración](https://www.afterpack.dev/es/docs/config): cada opción de arriba y qué superficie puede establecerla.
- [Directivas](https://www.afterpack.dev/es/docs/directives): la gramática completa de los marcadores.
- [Presets](https://www.afterpack.dev/es/docs/presets): la escala con la que se resuelve `preset`.
- [Build y CI](https://www.afterpack.dev/es/docs/builds): semillas, desarrollo frente a producción, promocionar los mismos bytes.
- [Protection Map](https://www.afterpack.dev/es/docs/protection-map): cómo leer el informe.
