> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Caché de paquetes e integración con optimize

> Usa optimizes() de Laravel 13 para integrar en el despliegue la generación y eliminación de la caché propia de tu paquete. A partir de la implementación, explica la clave de registro, las exclusiones, el orden de ejecución y el código de salida en caso de fallo.

Si tu paquete genera metadatos por adelantado, pedir a los usuarios que añadan un comando específico a su proceso de despliegue hace fácil que se olvide ejecutarlo al actualizar. Con `ServiceProvider::optimizes()` puedes incorporar los comandos de generación y eliminación a los comandos `optimize` y `optimize:clear` de Laravel.

Esta página parte de los [fundamentos del desarrollo de paquetes](/es/advanced/package-development) y revisa la implementación de Laravel Framework `v13.35.0`. No trata el formato de los archivos de caché, sino el contrato de registro y de operación.

## Separar el registro de comandos del registro de tareas

`commands()` registra las clases de comando que se pueden invocar desde Artisan. `optimizes()` es un proceso distinto que registra como tareas de optimización nombres de comandos que ya son ejecutables. Si solo llamas al segundo, las clases de comando no quedan registradas.

El siguiente ejemplo asume que el paquete ya implementa `CacheMetadataCommand` y `ClearMetadataCommand`, y que sus `$signature` son `courier:cache` y `courier:clear-cache`, respectivamente.

```php theme={null}
<?php

namespace Acme\Courier;

use Acme\Courier\Console\Commands\CacheMetadataCommand;
use Acme\Courier\Console\Commands\ClearMetadataCommand;
use Illuminate\Support\ServiceProvider;

class CourierServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        if ($this->app->runningInConsole()) {
            $this->commands([
                CacheMetadataCommand::class,
                ClearMetadataCommand::class,
            ]);

            $this->optimizes(
                optimize: 'courier:cache',
                clear: 'courier:clear-cache',
                key: 'acme-courier',
            );
        }
    }
}
```

Todos los argumentos de `optimizes()` son nullable, así que puedes registrar solo la generación o solo la eliminación. Aun así, indica siempre a los usuarios con qué procedimiento se invalida la caché generada.

## La clave de registro también es un contrato con el usuario

`ServiceProvider` guarda los comandos de generación en el array estático `$optimizeCommands` y los de eliminación en `$optimizeClearCommands`. En ambos casos, `key` se usa como clave del array.

Si omites `key`, el nombre se genera a partir del nombre de clase del provider. Por ejemplo, `CourierServiceProvider` da `courier`. Como solo se usa el nombre de la clase, pueden producirse colisiones incluso con providers del mismo nombre en otros espacios de nombres.

Si vuelves a registrar la misma clave, el comando de ese lado se sobrescribe con el valor posterior. Si quieres registrar varias tareas, usa claves distintas. Evita también las claves de las tareas estándar de Laravel, como `config` o `routes`, porque al combinar las tareas estándar con las del paquete, las claves de texto iguales también se sobrescriben.

<Tip>
  Indica explícitamente una clave que identifique el paquete, como `acme-courier`, y mantenla entre versiones. La clave se convierte en el nombre que se muestra para la tarea y también en el valor que los usuarios indican en `--except`.
</Tip>

## Se ejecutan después de las tareas estándar

En la implementación revisada, ambos comandos expanden el array registrado por los paquetes sobre el array de tareas estándar y luego las invocan en orden. Si usas una clave que no colisiona, las tareas del paquete se añaden después de las estándar.

| Comando | Orden de ejecución de las tareas estándar | Proceso posterior |
| - | - | - |
| `optimize` | `config:cache` → `event:cache` → `route:cache` → `view:cache` | Comandos de generación registrados |
| `optimize:clear` | `config:clear` → `cache:clear` → `clear-compiled` → `event:clear` → `route:clear` → `view:clear` | Comandos de eliminación registrados |

```mermaid theme={null}
flowchart TD
    A["boot() del provider"] --> B["Registrar comandos Artisan con commands()"]
    A --> C["Registrar clave y nombres de comando con optimizes()"]
    B --> D["php artisan optimize"]
    C --> D
    D --> E["Cachear configuración, eventos, rutas y vistas estándar"]
    E --> F["Ejecutar courier:cache"]
    C --> G["php artisan optimize:clear"]
    G --> H["Eliminar las cachés estándar"]
    H --> I["Ejecutar courier:clear-cache"]
```

Partiendo de este orden, el comando de generación no debe reconstruir otras cachés estándar, sino generar solo los datos que pertenecen al paquete. No uses `optimizes()` como API para controlar el orden de dependencias entre varios paquetes: si necesitas un orden estricto, enumera explícitamente los comandos específicos.

<Warning>
  `optimize:clear` también incluye `cache:clear`, que elimina los datos del almacén de caché por defecto. Si solo quieres borrar la caché propia del paquete, ejecuta `courier:clear-cache` directamente. Diseña además el comando de eliminación del paquete para que no haga flush de todo el almacén compartido y elimine solo las claves o archivos que le pertenecen.
</Warning>

## Excluir por clave o por nombre de comando

La opción `--except` de ambos comandos acepta valores separados por comas. Se eliminan los espacios al principio y al final de cada valor, y se excluyen las tareas cuya clave o nombre de comando coincida.

```bash theme={null}
php artisan optimize --except=acme-courier
php artisan optimize --except=courier:cache
php artisan optimize:clear --except=acme-courier,cache
```

Los dos primeros excluyen la misma tarea de generación. El tercero excluye la tarea de eliminación del paquete y el `cache:clear` estándar. `cache` es la clave de la tarea, no un nombre propio del paquete.

La exclusión solo afecta a esa ejecución. No es una configuración que desactive el registro del provider ni que elimine automáticamente una caché del paquete creada anteriormente.

## Distinguir el FAIL de una tarea del código de salida del comando padre

`OptimizeCommand` y `OptimizeClearCommand` invocan cada tarea con `callSilently()` y pasan a la visualización de la tarea si el código de salida es `0`. Como la salida normal de los comandos hijos no se muestra, para investigar la causa ejecuta directamente el comando específico.

En Laravel `v13.35.0`, ninguno de los dos `handle()` devuelve como valor de retorno del padre el código distinto de cero que devuelva un comando hijo. Aunque se muestre `FAIL` en pantalla, el bucle continúa y, si no hay excepciones, el código de salida del comando padre es `0`. En cambio, las excepciones lanzadas se vuelven a lanzar en el componente de visualización de tareas, así que no siguen el mismo comportamiento de continuar.

<Warning>
  No des por hecho que la caché del paquete se generó correctamente solo porque `php artisan optimize` terminó con código de salida `0`. Este comportamiento se basa en la implementación de la versión revisada, así que compruébalo también cuando actualices las versiones de Laravel compatibles.
</Warning>

Si la generación del paquete es un requisito obligatorio del despliegue, usa un procedimiento que permita comprobar directamente el código de salida del comando hijo. Por ejemplo, a continuación se excluye la tarea del paquete de la ejecución conjunta y se ejecuta directamente una sola vez después de las tareas estándar.

```bash theme={null}
php artisan optimize --except=acme-courier && php artisan courier:cache
```

Este ejemplo refleja en el código de salida el fallo de `courier:cache`, pero no agrega las salidas distintas de cero de las tareas estándar. En despliegues que también necesiten detectar con rigor los fallos de las tareas estándar, ejecuta por separado los comandos necesarios y comprueba sus códigos de salida.

## Diseño y verificación de una caché que resista las actualizaciones

Además del registro, define también las responsabilidades de los comandos y del lado que lee la caché.

* La generación debe llevar al mismo estado a partir de la misma entrada aunque se ejecute repetidamente, y no debe activar datos incompletos si falla a mitad del proceso.
* La eliminación debe completarse correctamente aunque no exista caché, y no debe borrar la configuración publicada ni los datos persistentes del usuario.
* Un comando cuya generación falle debe informar del error y devolver un valor distinto de cero. El lado que lee tampoco debe tratar incondicionalmente como válida una caché dañada.
* Si cambias el formato de la caché, indica a los usuarios que deben regenerarla y considera también reiniciar los procesos de larga duración.

Además de las pruebas del paquete, verifica lo siguiente en la aplicación que lo usa. Como los arrays de registro son estáticos, ten cuidado también con el estado de registro que se arrastra entre pruebas dentro del mismo proceso.

| Operación a verificar | Condición de finalización |
| - | - |
| Ejecutar directamente los comandos específicos de generación y eliminación | `0` en condiciones normales y distinto de cero si falla la generación. La eliminación tiene éxito aunque se ejecute dos veces |
| Ejecutar `optimize` / `optimize:clear` | Las tareas del paquete se invocan una vez cada una y el estado tras la generación y la eliminación es correcto |
| Indicar `--except` con la clave y con el nombre del comando | Solo deja de ejecutarse la tarea indicada |
| Hacer que el comando de generación termine con un valor distinto de cero | Se puede distinguir la indicación `FAIL` del código de salida del comando padre en la versión revisada |
| Regenerar tras actualizar el paquete | Se genera con el nuevo código y la nueva configuración, y no se sigue leyendo el formato antiguo |

## Páginas relacionadas

<Columns cols={2}>
  <Card title="Fusión y caché de la configuración de paquetes" icon="sliders" href="/es/advanced/package-config-merging">
    Repasa cómo se completan los valores de la configuración publicada y su relación con la reconstrucción de la caché de configuración.
  </Card>

  <Card title="Probar paquetes Laravel con Orchestra Testbench" icon="flask" href="/es/advanced/package-testing">
    Registra providers y comandos Artisan en el entorno de pruebas.
  </Card>
</Columns>

## Fuentes primarias consultadas

* [Documentación oficial de Laravel: Optimize commands](https://github.com/laravel/docs/blob/13.x/packages.md#optimize-commands)
* [ServiceProvider: optimizes() y la clave de registro](https://github.com/laravel/framework/blob/v13.35.0/src/Illuminate/Support/ServiceProvider.php)
* [OptimizeCommand: tareas y proceso de exclusión](https://github.com/laravel/framework/blob/v13.35.0/src/Illuminate/Foundation/Console/OptimizeCommand.php)
* [OptimizeClearCommand: tareas de eliminación y orden de ejecución](https://github.com/laravel/framework/blob/v13.35.0/src/Illuminate/Foundation/Console/OptimizeClearCommand.php)
* [Command: valor de retorno de handle() y código de salida](https://github.com/laravel/framework/blob/v13.35.0/src/Illuminate/Console/Command.php)
* [Task: visualización del resultado y relanzamiento de excepciones](https://github.com/laravel/framework/blob/v13.35.0/src/Illuminate/Console/View/Components/Task.php)


## Related topics

- [Desarrollo de paquetes para Laravel](/es/advanced/package-development.md)
- [Temas avanzados](/es/advanced/index.md)
- [Guía de desarrollo de apps con integración de la Engine API - VOICEVOX for Laravel](/es/packages/laravel-voicevox/app-guide.md)
- [Integración con Laravel AI SDK](/es/packages/laravel-copilot-sdk/ai-sdk.md)
- [Estructura interna de la detección automática de paquetes](/es/advanced/package-discovery.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.