Skip to main content
Aunque actualices el JavaScript o el CSS de tu paquete, los archivos ya copiados en el directorio public de la aplicación no cambian automáticamente. Para evitar que solo el código PHP pase a la nueva versión mientras el navegador sigue usando los assets antiguos, es necesario definir quién es el propietario del destino de publicación y cuál es el procedimiento de actualización. Esta página parte de los fundamentos del desarrollo de paquetes y organiza el diseño de la distribución y el mantenimiento a partir del proceso de publicación de Laravel 13. Para verificar la implementación se usa laravel/framework v13.35.0.

Publicar no es compilar ni sincronizar

ServiceProvider::publishes() registra el origen y el destino de la copia. Quien copia realmente los archivos es vendor:publish. No transpila JavaScript, no compila CSS ni añade nada a las entradas de Vite de la aplicación. Si el paquete distribuye archivos ya compilados, puedes usar, por ejemplo, la siguiente estructura.
En la primera publicación, indica explícitamente el provider y la etiqueta.
En este ejemplo se crean public/vendor/courier/courier.css y courier.js. Si el diseño consiste en distribuirlos como CSS y JavaScript normales, puedes referenciarlos desde Blade de la siguiente manera.
Si los distribuyes como ES modules, por ejemplo, adapta la forma de cargarlos al formato de distribución. asset() es un helper que genera URLs; no compila, no publica ni genera nombres de archivo basados en el contenido.
En el origen de la copia coloca únicamente artefactos compilados que se puedan publicar. En este ejemplo, el destino es public, accesible desde la web. No incluyas archivos de configuración ni datos internos en el mismo grupo de publicación.

Las etiquetas no son un espacio de nombres exclusivo del provider

ServiceProvider registra las rutas de publicación en un array por clase de provider y en otro por etiqueta. Como el array por etiqueta se comparte entre varios providers, usar una etiqueta genérica como public puede incluir también a otros paquetes. Cuando se indican ambos, pathsForProviderAndGroup() usa array_intersect_key() con la ruta de origen como clave. No es un mecanismo para cambiar a otro destino según la etiqueta. Evita diseños que registren el mismo origen varias veces para tener destinos distintos según el uso. --tag se puede indicar varias veces. En ese caso, cada etiqueta se publica por orden. --all retorna al principio del proceso de selección, por lo que, aunque añadas --provider o --tag al mismo tiempo, no se usan para filtrar.
Para no sobrescribir también la configuración y las vistas del usuario, usa en el procedimiento de actualización una etiqueta de assets propia del paquete. Si indicas solo el provider y añades --force, la configuración y las vistas del mismo provider también pueden verse afectadas.

Elegir la opción de republicación adecuada

La publicación de archivos y de directorios de VendorPublishCommand decide si copia en función de la existencia del archivo de destino y de las opciones. La siguiente tabla muestra el comportamiento para archivos de assets normales que existen en el origen. --existing no es una opción para proteger las modificaciones. Sobrescribe los archivos existentes, pero no publica los archivos añadidos en la nueva versión. En una actualización en la que el JavaScript necesite un archivo nuevo, --existing por sí solo puede dejar los artefactos incompletos. Si el contrato establece que el paquete gestiona el destino de publicación y que el usuario no lo edita directamente, ejecuta lo siguiente después de actualizar.
--force no fusiona diferencias y sobrescribe también las modificaciones del usuario. Separa el CSS que el usuario personaliza de los artefactos gestionados por el paquete, por ejemplo cargándolo como un archivo independiente. Define una política de actualización distinta de la de la personalización de la configuración y las vistas.

Los archivos eliminados permanecen en el destino

moveManagedFiles(), en la publicación de directorios, recorre los archivos del origen y los escribe. No existe ningún proceso que busque y elimine archivos que solo existan en el destino. --force tampoco realiza una sincronización completa del directorio. Por ejemplo, aunque elimines legacy.js en la nueva versión, si la versión anterior ya estaba publicada, public/vendor/courier/legacy.js permanece. Al renombrar un archivo también se conserva el archivo con el nombre antiguo, así que registra en las notas de la versión los archivos eliminados o renombrados y los cambios en las referencias. Si ofreces un procedimiento para eliminar los archivos antiguos, indica concretamente los archivos que pertenecen al paquete. No propongas un procedimiento que elimine por completo un directorio en el que el usuario pueda haber colocado archivos propios.

Participar en laravel-assets implica un contrato de sobrescritura

La plantilla oficial de aplicación de Laravel 13 incluye el siguiente script en post-update-cmd de composer.json.
Se trata de un script de la aplicación. No es la detección automática de paquetes la que actualiza los archivos publicados. En aplicaciones existentes, el script puede haberse modificado o eliminado, así que comprueba la configuración del lado del usuario. Para participar en esta vía de actualización, cambia el segundo argumento del publishes() anterior a un array y registra los mismos assets en dos etiquetas.
laravel-assets no es una etiqueta con un proceso de copia especial. Como el script de la plantilla publica esa etiqueta con --force, los archivos que participan se sobrescriben al actualizar con Composer. No registres la configuración ni las vistas que el usuario edita.
La actualización automática presupone que la aplicación tenga el script, que se ejecute ese evento y que el provider registre las rutas de publicación. Para que la actualización sea posible también en despliegues que no cumplen estas condiciones, documenta el comando de republicación con la etiqueta propia del paquete.

Alinear las versiones de PHP y de los assets en el despliegue

config:cache y view:cache no reescriben el JavaScript ni el CSS publicados. Si el diseño sirve los archivos con la misma URL después de publicarlos, la caché del navegador o de la CDN puede hacer que se use el contenido antiguo. Incluye también en el procedimiento de actualización la política de entrega de la aplicación, como URLs que reflejen la versión de los artefactos o la invalidación de la caché. En cada versión, comprueba las siguientes combinaciones.
  • En una aplicación sin publicar, se publican todos los archivos compilados necesarios.
  • Con la versión anterior ya publicada, --force actualiza los archivos existentes y añade los nuevos.
  • La actualización de los assets no sobrescribe la configuración, las vistas ni el CSS propio del usuario.
  • Se indica cómo tratar los archivos eliminados o renombrados y no quedan referencias a la versión anterior.
  • El contenido de la nueva versión llega a través de la URL de entrega real, y el procesamiento de PHP y del navegador funciona de forma coordinada.

Páginas relacionadas

Detección automática de paquetes

Revisa las diferencias entre la actualización de Composer, la detección de providers y la publicación de archivos.

Sobrescritura y actualización de vistas de paquetes

Revisa la política de mantenimiento de las plantillas que personaliza el usuario.

Caché de paquetes e integración con optimize

Explica la caché del paquete, que se gestiona por separado de la publicación de archivos.

Gestión de la compatibilidad de versiones

Trata los cambios en el destino de publicación y el formato de distribución como un contrato de compatibilidad.

Fuentes primarias consultadas

Última modificación el 7 de octubre de 2026