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

# Assets publics d'un package et mises à jour

> En partant du mécanisme de publication de Laravel 13, découvrez dans une optique de maintenance à long terme la distribution de JavaScript et de CSS, la portée de sélection des tags, les options d'écrasement et la republication lors des mises à jour Composer.

Même si vous mettez à jour le JavaScript ou le CSS de votre package, les fichiers déjà copiés dans le répertoire `public` de l'application ne changent pas automatiquement. Pour éviter que seul le code PHP passe à la nouvelle version tandis que le navigateur continue d'utiliser les anciens assets, vous devez définir à qui appartient la destination de publication et quelle est la procédure de mise à jour.

Cette page part des [bases du développement de packages](/fr/advanced/package-development) et organise la conception de la distribution et de la maintenance à partir du mécanisme de publication de Laravel 13. L'implémentation a été vérifiée avec `laravel/framework` `v13.35.0`.

## La publication n'est ni un build ni une synchronisation

`ServiceProvider::publishes()` enregistre une source et une destination de copie. C'est `vendor:publish` qui copie réellement les fichiers. Cette commande ne transpile pas le JavaScript, ne compile pas le CSS et n'ajoute rien aux points d'entrée Vite de l'application.

Si votre package distribue des fichiers déjà compilés, utilisez par exemple la structure suivante.

```text theme={null}
courier/
├── public/
│   ├── courier.css
│   └── courier.js
└── src/
    └── CourierServiceProvider.php
```

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

namespace Acme\Courier;

use Illuminate\Support\ServiceProvider;

class CourierServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        if ($this->app->runningInConsole()) {
            $this->publishes([
                __DIR__.'/../public' => public_path('vendor/courier'),
            ], 'courier-assets');
        }
    }
}
```

Lors de la première publication, indiquez explicitement le provider et le tag.

```bash theme={null}
php artisan vendor:publish --provider="Acme\Courier\CourierServiceProvider" --tag=courier-assets
```

Dans cet exemple, `public/vendor/courier/courier.css` et `courier.js` sont créés. Si vous les distribuez comme des fichiers CSS et JavaScript ordinaires, vous pouvez les référencer depuis Blade comme suit.

```blade theme={null}
<link rel="stylesheet" href="{{ asset('vendor/courier/courier.css') }}">
<script src="{{ asset('vendor/courier/courier.js') }}" defer></script>
```

Si vous les distribuez sous forme de modules ES, par exemple, adaptez la méthode de chargement au format de distribution. `asset()` est un helper qui génère une URL : il ne compile pas, ne publie pas et ne génère pas de noms de fichiers en fonction du contenu.

<Warning>
  Ne placez dans la source de copie que des artefacts de build qui peuvent être rendus publics. Dans cet exemple, la destination est `public`, accessible depuis le Web. N'incluez pas de fichiers de configuration ni de données internes dans le même groupe de publication.
</Warning>

## Un tag n'est pas un namespace propre au provider

`ServiceProvider` enregistre les chemins de publication dans un tableau par classe de provider et dans un tableau par tag. Le tableau par tag étant partagé entre plusieurs providers, un tag générique comme `public` peut aussi cibler d'autres packages.

| Option | Chemins de publication sélectionnés |
| - | - |
| `--tag=courier-assets` | Les chemins de tous les providers ayant enregistré ce tag |
| `--provider="Acme\Courier\CourierServiceProvider"` | Tous les chemins enregistrés par ce provider |
| Provider et tag à la fois | L'intersection des chemins de ce provider et de ceux de ce tag |
| `--all` | Les chemins de publication de tous les providers |

Lorsque les deux sont spécifiés, `pathsForProviderAndGroup()` utilise `array_intersect_key()` **en prenant le chemin source comme clé**. Ce n'est pas un mécanisme qui bascule vers une autre destination selon le tag. Évitez une conception qui enregistre plusieurs fois la même source pour lui associer des destinations différentes selon l'usage.

`--tag` peut être répété. Dans ce cas, chaque tag est publié successivement. Comme `--all` provoque un retour dès le début du traitement de sélection, ajouter `--provider` ou `--tag` en même temps ne restreint pas la sélection.

<Tip>
  Pour ne pas écraser la configuration ou les vues de l'utilisateur, utilisez un tag d'assets propre à votre package dans la procédure de mise à jour. Si vous indiquez uniquement le provider avec `--force`, la configuration et les vues de ce même provider peuvent aussi être ciblées.
</Tip>

## Choisir les options de republication

La publication de fichiers et de répertoires de `VendorPublishCommand` décide de la copie en fonction de l'existence du fichier de destination et des options. Le tableau suivant décrit le comportement pour les fichiers d'assets ordinaires présents dans la source.

| Option | Fichier absent de la destination | Fichier présent dans la destination |
| - | - | - |
| Aucune | Ajouté | Conservé |
| `--force` | Ajouté | Écrasé |
| `--existing` | Non ajouté | Écrasé |
| `--existing --force` | Non ajouté | Écrasé |

`--existing` n'est pas une option qui protège les modifications. Elle écrase les fichiers existants, mais ne publie pas les fichiers ajoutés dans la nouvelle version. Lors d'une mise à jour où le JavaScript a besoin de nouveaux fichiers, `--existing` seul risque de ne pas fournir l'ensemble des artefacts.

Si le contrat prévoit que le package gère la destination et que l'utilisateur ne la modifie pas directement, exécutez la commande suivante après la mise à jour.

```bash theme={null}
php artisan vendor:publish --provider="Acme\Courier\CourierServiceProvider" --tag=courier-assets --force
```

<Warning>
  `--force` ne fusionne pas les différences et écrase aussi les modifications de l'utilisateur. Séparez le CSS personnalisé par l'utilisateur des artefacts gérés par le package, par exemple en le chargeant dans un fichier distinct. Distinguez aussi la politique de mise à jour de celle qui s'applique à la personnalisation de la configuration et des vues.
</Warning>

### Les fichiers supprimés restent dans la destination

`moveManagedFiles()`, utilisé pour la publication de répertoires, parcourt les fichiers présents dans la source et les écrit. Aucun traitement ne recherche ni ne supprime les fichiers qui n'existent que dans la destination. `--force` ne réalise pas non plus une synchronisation complète du répertoire.

Par exemple, même si vous supprimez `legacy.js` dans la nouvelle version, `public/vendor/courier/legacy.js` reste en place si l'ancienne version a déjà été publiée. En cas de renommage, le fichier portant l'ancien nom reste également : consignez donc dans les notes de version les fichiers supprimés ou renommés ainsi que les changements de références.

Si vous fournissez une procédure pour supprimer les anciens fichiers, indiquez précisément les fichiers appartenant au package. Ne proposez pas de supprimer entièrement un répertoire susceptible de contenir des fichiers propres à l'utilisateur.

## Participer à laravel-assets implique un contrat d'écrasement

Le squelette d'application officiel de Laravel 13 contient le script suivant dans `post-update-cmd` de `composer.json`.

```json theme={null}
{
    "scripts": {
        "post-update-cmd": [
            "@php artisan vendor:publish --tag=laravel-assets --ansi --force"
        ]
    }
}
```

Il s'agit d'un script de l'application. Ce n'est pas la découverte automatique des packages elle-même qui met à jour les fichiers publiés. Dans une application existante, le script peut avoir été modifié ou supprimé : vérifiez donc la configuration côté utilisateur.

Pour participer à ce chemin de mise à jour, transformez le second argument de `publishes()` vu précédemment en tableau afin d'enregistrer les mêmes assets sous deux tags.

```php theme={null}
$this->publishes([
    __DIR__.'/../public' => public_path('vendor/courier'),
], ['courier-assets', 'laravel-assets']);
```

`laravel-assets` n'est pas un tag doté d'un traitement de copie particulier. Comme le script du squelette publie ce tag avec `--force`, les fichiers qui y participent sont écrasés lors des mises à jour Composer. N'y enregistrez pas la configuration ni les vues que l'utilisateur modifie.

<Info>
  La mise à jour automatique suppose que le script existe dans l'application, que l'événement correspondant est exécuté et que le provider enregistre les chemins de publication. Pour que la mise à jour reste possible dans les déploiements qui ne remplissent pas ces conditions, indiquez une commande de republication utilisant le tag propre au package.
</Info>

## Aligner les versions PHP et des assets lors du déploiement

```mermaid theme={null}
flowchart TD
    A["Mise à jour du package"] --> B["Enregistrement des chemins de publication"]
    B --> C["vendor:publish --force avec le tag propre<br>ou script de mise à jour laravel-assets"]
    C --> D["Ajout des nouveaux fichiers<br>Écrasement des fichiers existants"]
    D --> E["Nettoyage des anciens fichiers indiqués<br>Application de la politique de cache navigateur et CDN"]
    E --> F["Vérification que PHP et les assets fonctionnent dans la même version"]
```

`config:cache` et `view:cache` ne réécrivent pas le JavaScript ni le CSS publiés. Si vous continuez à servir les fichiers à la même URL après publication, le cache du navigateur ou du CDN peut entraîner l'utilisation d'un ancien contenu. Incluez aussi dans la procédure de mise à jour la politique de distribution de l'application, comme des URL reflétant la version des artefacts ou l'invalidation du cache.

À chaque version, vérifiez les combinaisons suivantes.

* Dans une application où rien n'a encore été publié, tous les fichiers compilés nécessaires sont publiés.
* Lorsque l'ancienne version a déjà été publiée, `--force` met à jour les fichiers existants et ajoute les nouveaux fichiers.
* La mise à jour des assets n'écrase ni la configuration, ni les vues, ni le CSS personnalisé de l'utilisateur.
* Le traitement des fichiers supprimés ou renommés est explicite et aucune référence à l'ancienne version ne subsiste.
* Le contenu de la nouvelle version est bien servi aux URL de distribution réelles, et le traitement PHP et celui du navigateur fonctionnent ensemble.

## Pages associées

<Columns cols={2}>
  <Card title="Découverte automatique des packages" icon="magnifying-glass" href="/fr/advanced/package-discovery">
    Les différences entre les mises à jour Composer, la découverte des providers et la publication de fichiers.
  </Card>

  <Card title="Surcharger et mettre à jour les vues d'un package" icon="eye" href="/fr/advanced/package-views">
    La politique de maintenance des templates personnalisés par l'utilisateur.
  </Card>

  <Card title="Cache d'un package et intégration à optimize" icon="gears" href="/fr/advanced/package-optimization">
    Le cache de package, géré séparément de la publication de fichiers.
  </Card>

  <Card title="Gestion de la compatibilité de versions" icon="code-branch" href="/fr/advanced/package-versioning">
    Traiter les changements de destination et de format de distribution comme un contrat de compatibilité.
  </Card>
</Columns>

## Sources primaires consultées

* [Documentation officielle de Laravel : Public assets](https://github.com/laravel/docs/blob/13.x/packages.md#public-assets)
* [Documentation officielle de Laravel : Publishing file groups](https://github.com/laravel/docs/blob/13.x/packages.md#publishing-file-groups)
* [Laravel Framework v13.35.0 : ServiceProvider](https://github.com/laravel/framework/blob/v13.35.0/src/Illuminate/Support/ServiceProvider.php) — `publishes()`, `addPublishGroup()`, `pathsToPublish()`, `pathsForProviderAndGroup()`.
* [Laravel Framework v13.35.0 : VendorPublishCommand](https://github.com/laravel/framework/blob/v13.35.0/src/Illuminate/Foundation/Console/VendorPublishCommand.php) — portée de sélection, conditions d'écrasement et copie au sein des répertoires.
* [Squelette d'application officiel de Laravel 13 : composer.json](https://github.com/laravel/laravel/blob/13.x/composer.json) — republication de `laravel-assets` via `post-update-cmd`.


## Related topics

- [Développement de packages Laravel](/fr/advanced/package-development.md)
- [Sujets avancés](/fr/advanced/index.md)
- [Publier et mettre à jour les migrations d'un package](/fr/advanced/package-migrations.md)
- [Surcharger et mettre à jour les vues d'un package](/fr/advanced/package-views.md)
- [Cache d'un package et intégration à optimize](/fr/advanced/package-optimization.md)


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