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

# Öffentliche Paket-Assets veröffentlichen und aktualisieren

> Anhand der Publish-Verarbeitung von Laravel 13 erläutert: Auslieferung von JavaScript und CSS, Auswahlbereich von Tags, Optionen zum Überschreiben und erneutes Veröffentlichen bei Composer-Updates – aus Sicht der langfristigen Wartung.

Wenn Sie JavaScript oder CSS Ihres Pakets aktualisieren, ändern sich die bereits in das `public`-Verzeichnis der Anwendung kopierten Dateien nicht automatisch. Damit nicht nur der PHP-Code auf die neue Version wechselt, während der Browser weiterhin die alten Assets verwendet, müssen Sie festlegen, wem das Zielverzeichnis gehört und wie Updates ablaufen.

Diese Seite setzt die [Grundlagen der Paketentwicklung](/de/advanced/package-development) voraus und leitet aus der Publish-Verarbeitung von Laravel 13 ein Konzept für Auslieferung und Wartung ab. Die Implementierung wurde anhand von `laravel/framework` `v13.35.0` geprüft.

## Veröffentlichen ist weder Build noch Synchronisation

`ServiceProvider::publishes()` registriert Quelle und Ziel einer Kopie. Die Dateien tatsächlich kopiert erst `vendor:publish`. JavaScript wird dabei weder transpiliert noch CSS gebaut, und es werden auch keine Einträge zu den Vite-Einstiegspunkten der Anwendung hinzugefügt.

Wenn das Paket bereits gebaute Dateien ausliefert, sieht die Struktur zum Beispiel so aus:

```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');
        }
    }
}
```

Geben Sie beim ersten Veröffentlichen Provider und Tag explizit an.

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

In diesem Beispiel entstehen `public/vendor/courier/courier.css` und `courier.js`. Werden sie als gewöhnliches CSS und JavaScript ausgeliefert, können Sie sie in Blade so referenzieren:

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

Wenn Sie etwa ES-Module ausliefern, passen Sie die Art des Ladens an das Auslieferungsformat an. `asset()` ist ein Helper, der URLs erzeugt; er baut nichts, veröffentlicht nichts und erzeugt keine inhaltsabhängigen Dateinamen.

<Warning>
  Legen Sie in der Quelle nur Build-Artefakte ab, die veröffentlicht werden dürfen. Das Ziel in diesem Beispiel ist das über das Web erreichbare `public`. Nehmen Sie keine Konfigurationsdateien oder internen Daten in dieselbe Publish-Gruppe auf.
</Warning>

## Tags sind kein providerspezifischer Namensraum

`ServiceProvider` registriert Publish-Pfade sowohl in einem Array pro Provider-Klasse als auch in einem Array pro Tag. Das Array pro Tag wird von allen Providern gemeinsam genutzt. Verwenden Sie einen allgemeinen Tag wie `public`, können daher auch andere Pakete erfasst werden.

| Angabe | Ausgewählte Publish-Pfade |
| - | - |
| `--tag=courier-assets` | Pfade aller Provider, die diesen Tag registriert haben |
| `--provider="Acme\Courier\CourierServiceProvider"` | Alle von diesem Provider registrierten Pfade |
| Provider und Tag zusammen | Schnittmenge der Pfade dieses Providers und der Pfade dieses Tags |
| `--all` | Publish-Pfade aller Provider |

Werden beide angegeben, verwendet `pathsForProviderAndGroup()` `array_intersect_key()` **mit dem Quellpfad als Schlüssel**. Es handelt sich also nicht um einen Mechanismus, der je nach Tag auf ein anderes Ziel umschaltet. Vermeiden Sie Konzepte, bei denen dieselbe Quelle mehrfach registriert wird, um je nach Zweck unterschiedliche Ziele zu erhalten.

`--tag` kann mehrfach angegeben werden; die Tags werden dann nacheinander veröffentlicht. `--all` kehrt gleich zu Beginn der Auswahl zurück. Geben Sie zusätzlich `--provider` oder `--tag` an, wird damit also nicht eingeschränkt.

<Tip>
  Verwenden Sie in Update-Anleitungen einen paketspezifischen Asset-Tag, damit Konfigurationen und Views der Nutzer nicht überschrieben werden. Geben Sie nur den Provider zusammen mit `--force` an, können auch Konfigurationen und Views desselben Providers erfasst werden.
</Tip>

## Optionen für erneutes Veröffentlichen gezielt einsetzen

Beim Veröffentlichen von Dateien und Verzeichnissen entscheidet `VendorPublishCommand` anhand der Existenz der Zieldatei und der Optionen, ob kopiert wird. Die folgende Tabelle zeigt das Verhalten für gewöhnliche Asset-Dateien, die in der Quelle vorhanden sind.

| Option | Datei fehlt im Ziel | Datei existiert im Ziel |
| - | - | - |
| Keine | Wird hinzugefügt | Bleibt erhalten |
| `--force` | Wird hinzugefügt | Wird überschrieben |
| `--existing` | Wird nicht hinzugefügt | Wird überschrieben |
| `--existing --force` | Wird nicht hinzugefügt | Wird überschrieben |

`--existing` ist keine Option zum Schutz von Änderungen. Sie überschreibt vorhandene Dateien, veröffentlicht aber keine Dateien, die in der neuen Version hinzugekommen sind. Benötigt das JavaScript nach einem Update neue zusätzliche Dateien, sind die Artefakte mit `--existing` allein möglicherweise unvollständig.

Wenn die Vereinbarung lautet, dass das Paket das Ziel verwaltet und Nutzer es nicht direkt bearbeiten, führen Sie nach dem Update Folgendes aus:

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

<Warning>
  `--force` führt Unterschiede nicht zusammen und überschreibt auch Änderungen der Nutzer. Trennen Sie CSS, das Nutzer anpassen, von den vom Paket verwalteten Artefakten, indem Sie es zum Beispiel als separate Datei laden. Legen Sie für Anpassungen von Konfigurationen und Views eine eigene Update-Strategie fest.
</Warning>

### Gelöschte Dateien bleiben im Ziel erhalten

`moveManagedFiles()` beim Veröffentlichen von Verzeichnissen durchläuft die Dateien in der Quelle und schreibt sie. Dateien, die nur im Ziel existieren, werden weder gesucht noch gelöscht. Auch `--force` führt keine vollständige Synchronisation des Verzeichnisses durch.

Löschen Sie zum Beispiel in einer neuen Version `legacy.js`, bleibt `public/vendor/courier/legacy.js` erhalten, wenn die alte Version bereits veröffentlicht wurde. Auch bei Umbenennungen bleibt die Datei mit dem alten Namen bestehen. Dokumentieren Sie daher in den Release Notes gelöschte und umbenannte Dateien sowie geänderte Referenzen.

Wenn Sie eine Anleitung zum Entfernen alter Dateien bereitstellen, nennen Sie konkret die Dateien, die dem Paket gehören. Formulieren Sie keine Schritte, die ein ganzes Verzeichnis löschen, in dem möglicherweise eigene Dateien der Nutzer liegen.

## Teilnahme an laravel-assets bedeutet eine Vereinbarung zum Überschreiben

Das offizielle Anwendungsgerüst von Laravel 13 enthält in `composer.json` unter `post-update-cmd` folgendes Skript:

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

Dies ist ein Skript auf Seiten der Anwendung. Die automatische Paket-Erkennung selbst aktualisiert keine veröffentlichten Dateien. In bestehenden Anwendungen kann das Skript geändert oder entfernt worden sein, prüfen Sie daher die Konfiguration auf Nutzerseite.

Um an diesem Update-Pfad teilzunehmen, ändern Sie das zweite Argument des obigen `publishes()` in ein Array und registrieren dieselben Assets unter zwei Tags.

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

`laravel-assets` ist kein Tag mit besonderer Kopierlogik. Da das Skript des Gerüsts diesen Tag mit `--force` veröffentlicht, werden teilnehmende Dateien bei Composer-Updates überschrieben. Registrieren Sie dort keine Konfigurationen oder Views, die Nutzer bearbeiten.

<Info>
  Voraussetzung für das automatische Update ist, dass das Skript in der Anwendung vorhanden ist, das Ereignis ausgeführt wird und der Provider die Publish-Pfade registriert. Damit auch Deployments ohne diese Voraussetzungen aktualisiert werden können, dokumentieren Sie einen Befehl zum erneuten Veröffentlichen mit dem paketspezifischen Tag.
</Info>

## Beim Deployment die Versionen von PHP und Assets angleichen

```mermaid theme={null}
flowchart TD
    A["Paket aktualisieren"] --> B["Publish-Pfade registrieren"]
    B --> C["vendor:publish --force mit eigenem Tag<br>oder Update-Skript für laravel-assets"]
    C --> D["Neue Dateien hinzufügen<br>Vorhandene Dateien überschreiben"]
    D --> E["Angegebene alte Dateien bereinigen<br>Cache-Strategie für Browser und CDN anwenden"]
    E --> F["Prüfen, dass PHP und Assets in derselben Version laufen"]
```

`config:cache` und `view:cache` verändern veröffentlichtes JavaScript und CSS nicht. Wird nach dem Veröffentlichen weiterhin unter derselben URL ausgeliefert, können durch Browser- oder CDN-Caches alte Inhalte verwendet werden. Nehmen Sie deshalb auch die Auslieferungsstrategie der Anwendung in die Update-Schritte auf, etwa URLs, die die Version der Artefakte widerspiegeln, oder das Invalidieren von Caches.

Prüfen Sie bei jedem Release folgende Kombinationen:

* In einer Anwendung ohne bisherige Veröffentlichung werden alle benötigten gebauten Dateien veröffentlicht.
* Ist die alte Version bereits veröffentlicht, aktualisiert `--force` vorhandene Dateien und fügt neue Dateien hinzu.
* Asset-Updates überschreiben keine Konfigurationen, Views oder eigenes CSS der Nutzer.
* Der Umgang mit gelöschten und umbenannten Dateien ist dokumentiert, und es verbleiben keine Referenzen auf die alte Version.
* Unter der tatsächlichen Auslieferungs-URL kommt der Inhalt der neuen Version an, und PHP sowie die browserseitige Verarbeitung arbeiten zusammen.

## Verwandte Seiten

<Columns cols={2}>
  <Card title="Interne Struktur der automatischen Paket-Erkennung" icon="magnifying-glass" href="/de/advanced/package-discovery">
    Unterschiede zwischen Composer-Updates, Provider-Erkennung und dem Veröffentlichen von Dateien.
  </Card>

  <Card title="Paket-Views überschreiben und aktualisieren" icon="eye" href="/de/advanced/package-views">
    Wartungsstrategien für Templates, die Nutzer anpassen.
  </Card>

  <Card title="Paket-Caches in optimize integrieren" icon="gears" href="/de/advanced/package-optimization">
    Erläutert Paket-Caches, die getrennt vom Veröffentlichen von Dateien verwaltet werden.
  </Card>

  <Card title="Versionskompatibilität von Paketen verwalten" icon="code-branch" href="/de/advanced/package-versioning">
    Änderungen an Zielen und Auslieferungsformaten als Kompatibilitätsvereinbarung behandeln.
  </Card>
</Columns>

## Herangezogene Primärquellen

* [Offizielle Laravel-Dokumentation: Public assets](https://github.com/laravel/docs/blob/13.x/packages.md#public-assets)
* [Offizielle Laravel-Dokumentation: 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) – Auswahlbereich, Bedingungen für das Überschreiben und Kopiervorgang innerhalb von Verzeichnissen.
* [Offizielles Anwendungsgerüst von Laravel 13: composer.json](https://github.com/laravel/laravel/blob/13.x/composer.json) – Erneutes Veröffentlichen von `laravel-assets` über `post-update-cmd`.


## Related topics

- [Laravel-Paketentwicklung](/de/advanced/package-development.md)
- [Weiterführende Themen](/de/advanced/index.md)
- [Paket-Migrationen veröffentlichen und aktualisieren](/de/advanced/package-migrations.md)
- [Paket-Views überschreiben und aktualisieren](/de/advanced/package-views.md)
- [Google Sheets API for Laravel](/de/packages/laravel-google-sheets/index.md)


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