Skip to main content

Qu’est-ce qu’un package ?

Dans Laravel, un package est un package Composer qui ajoute des fonctionnalités à votre application. Il en existe globalement deux types :
  • Package autonome — bibliothèque PHP générique qui ne dépend pas de Laravel (par exemple : Carbon, Pest)
  • Package Laravel — package intégré à Laravel qui expose des routes, des contrôleurs, des vues, de la configuration, etc.
Ce guide traite du second cas, à savoir le développement de packages spécifiques à Laravel. Concevoir un tel package suppose une bonne connaissance de la structure interne de Laravel : service providers, façades, publication de fichiers de configuration, etc.
Pour tester votre package, utilisez Orchestra Testbench. Vous pourrez écrire les tests de votre package comme s’il s’agissait d’une application Laravel classique.

Découverte automatique des packages

Lorsqu’un package est installé, Laravel lit la section extra.laravel de son composer.json afin d’enregistrer automatiquement les service providers et les façades.
Grâce à cette configuration, l’utilisateur n’a plus besoin d’éditer manuellement bootstrap/providers.php : le package est chargé automatiquement.
Le fonctionnement interne de la découverte automatique et le moment où le cache est reconstruit sont détaillés dans Fonctionnement interne de la découverte de packages.

Désactiver la découverte automatique

Si un utilisateur souhaite désactiver la découverte automatique pour un package donné, il peut le déclarer dans le composer.json de son application.

Rôle du service provider

Le service provider est le point d’entrée d’un package. C’est là que l’on centralise l’enregistrement des ressources (vues, configuration, migrations, routes…) auprès de Laravel. Le service provider hérite de Illuminate\Support\ServiceProvider et possède deux méthodes : register et boot.
N’enregistrez ni écouteurs d’événements, ni routes, ni vues dans la méthode register. Vous risqueriez d’utiliser par erreur un service issu d’un autre service provider pas encore chargé. Tout traitement autre qu’un binding doit se faire dans boot.
Pour étendre un service sans le créer avant son utilisation, et appliquer la configuration même s’il a déjà été résolu, consultez Hooks de résolution des services d’un package. Cette page explique quand callAfterResolving() s’exécute et comment concevoir un code qui supporte les applications répétées. Pour des méthodes d’enregistrement qui ne conservent pas d’état d’un traitement à l’autre, même avec Octane ou les workers de file d’attente, consultez Conception du cycle de vie des services d’un package. Cette page explique l’implémentation interne de scoped() et les points d’attention concernant les dépendances conservées par les singletons.

Publication du fichier de configuration

publishes() — publier des fichiers

En appelant publishes() dans boot, vous permettez aux utilisateurs de copier le fichier de configuration dans leur application via la commande vendor:publish.
Une fois publié, l’accès à la configuration se fait de manière classique :

mergeConfigFrom() — fusionner avec des valeurs par défaut

En utilisant mergeConfigFrom() dans la méthode register, vous garantissez que les valeurs par défaut du package sont utilisées même lorsque l’utilisateur n’a pas publié le fichier de configuration.
mergeConfigFrom() ne fusionne pas les tableaux imbriqués en profondeur. Sur des configurations comportant des tableaux multidimensionnels, une définition partielle par l’utilisateur peut empêcher la fusion des options restantes.
Pour la différence avec la méthode de remplacement récursif de Laravel 13, le traitement des listes à clés numériques et la procédure de mise à jour lorsque vous utilisez le cache de configuration, consultez Fusion et cache de la configuration des packages.

Séparer les groupes de publication par tag

En passant un tag comme deuxième argument à publishes(), vous permettez aux utilisateurs de publier uniquement les ressources dont ils ont besoin.

Enregistrement des routes

Utilisez loadRoutesFrom() pour charger un fichier de routes. Si le cache des routes de l’application est actif, le chargement est automatiquement ignoré.
Dans le fichier de routes, référencez les contrôleurs du package :
La déclaration explicite des middlewares, la prévention des conflits d’URI et de noms de route, ainsi que la procédure pour répercuter les changements de configuration dans le cache, sont expliquées dans Enregistrement et cache des routes d’un package.

Publication des migrations

publishesMigrations() permet d’enregistrer les fichiers de migration pour la publication. Dans la configuration par défaut de Laravel 13, database.migrations.update_date_on_publish est activé : l’horodatage du nom de fichier est donc mis à jour lors de la publication. Si ce paramètre est désactivé ou absent, cette mise à jour n’a pas lieu.
Le choix entre publication et chargement direct, les conditions de changement d’horodatage, les risques de la republication et les changements de schéma pour les utilisateurs existants sont expliqués dans Publier et mettre à jour les migrations d’un package.

Publication des vues

loadViewsFrom() — enregistrer un dossier de vues

loadViewsFrom() enregistre un dossier de vues. Le namespace passé en deuxième argument permet ensuite de référencer les vues sous la forme package::view.
Une fois enregistrée, chaque vue s’utilise via le namespace du package :
Laravel cherche les vues à deux emplacements : d’abord dans resources/views/vendor/courier de l’application, puis, à défaut, dans le dossier de vues du package. Cela permet aux utilisateurs de personnaliser les vues. L’ordre de recherche réel et le repli fichier par fichier, la manière de livrer les changements aux templates publiés, ainsi que la différence avec le cache Blade, sont expliqués dans Surcharger et mettre à jour les vues d’un package.

Publier les vues

Enregistrer des composants Blade

Si votre package fournit des composants Blade, enregistrez-les dans la méthode boot.
Vous pouvez également enregistrer un namespace entier de composants en une seule fois.

Distribution des assets publics

Pour distribuer le JavaScript, le CSS ou les images de votre package, enregistrez avec publishes() une copie vers un emplacement tel que public_path('vendor/courier'). Les fichiers déjà publiés ne changent pas automatiquement lorsque vous mettez à jour le package. La restriction des cibles par tag et par provider, la différence entre --force et --existing, le traitement des fichiers supprimés et la mise à jour via laravel-assets sont expliqués dans Assets publics d’un package et mises à jour.

Publication des fichiers de traduction

loadTranslationsFrom() enregistre les fichiers de traduction. Les traductions se référencent sous la forme package::file.key.
Pour des fichiers de traduction au format JSON, utilisez loadJsonTranslationsFrom().
La surcharge partielle des traductions PHP, l’ordre de chargement et la destination de surcharge des traductions JSON, ainsi que la compatibilité des clés de traduction et la mise à jour des fichiers publiés sont expliqués dans Surcharge et mise à jour des traductions d’un package.

Enregistrement des commandes

Les commandes Artisan du package sont enregistrées via la méthode commands(). Il est courant de ne les enregistrer que dans l’environnement console.

Intégration à la commande optimize

Si le package possède son propre cache, la méthode optimizes() permet de l’intégrer aux commandes php artisan optimize et php artisan optimize:clear.
L’enregistrement des classes de commande et l’enregistrement des tâches d’optimisation sont deux opérations distinctes. Les collisions de clés d’enregistrement, l’exclusion avec --except, l’ordre d’exécution par rapport aux tâches standard et les codes de sortie en cas d’échec sont expliqués dans Cache d’un package et intégration à optimize.

Ajouter des informations à la commande about

Pour ajouter des informations sur votre package dans la sortie de php artisan about, utilisez AboutCommand::add().
Le moment où les données sont évaluées, --only et la sortie JSON, une conception qui n’expose aucun secret et l’état d’enregistrement dans les tests sont détaillés dans Ajouter des informations de diagnostic du package à about.

Créer une façade

Les façades permettent d’appeler un binding du service container comme s’il s’agissait d’une méthode statique.
1

Créer la classe de service

2

Créer la classe façade

Héritez de Illuminate\Support\Facades\Facade et renvoyez la clé du binding du service container depuis getFacadeAccessor().
3

Déclarer le binding dans le service provider

4

Déclarer la façade dans composer.json

En ajoutant des annotations PHPDoc @method aux méthodes de la façade, vous activez l’autocomplétion dans les IDE.

DeferrableProvider — mettre en place le chargement différé

Un provider qui se contente d’enregistrer des bindings dans le service container peut être chargé de manière différée en implémentant l’interface DeferrableProvider. Le provider n’est chargé que lorsque le service est effectivement requis, ce qui améliore les performances de l’application.
Laravel compile et stocke la liste des services fournis par les deferred providers. Le provider n’est chargé qu’au moment où un des services listés dans provides() est résolu.
N’utilisez pas DeferrableProvider pour un provider qui doit enregistrer des ressources (vues, routes, écouteurs d’événements…). Si le provider est différé, ces ressources ne seront jamais enregistrées.

Tester un package

Pour tester un package indépendamment, utilisez Orchestra Testbench. Vous pourrez écrire les tests comme si vous étiez dans une application Laravel classique.
Dans votre classe de test, surchargez getPackageProviders() pour enregistrer les service providers du package.

Publication sur Composer

Voici quelques bonnes pratiques pour publier votre package sur Packagist. Configuration de base du composer.json
En dépendant de illuminate/support plutôt que de illuminate/framework, vous n’importez que les composants de Laravel dont vous avez réellement besoin. Gardez l’arbre de dépendances de votre package aussi léger que possible.
Exemple de structure de répertoires

Pages associées

Service providers

Revenez sur les méthodes register et boot des service providers et sur les deferred providers.

Gestion de la compatibilité entre versions

Découvrez les stratégies pour prendre en charge les montées de version majeures de Laravel et PHP ainsi que la configuration d’une matrice de tests GitHub Actions.
Dernière modification le 14 octobre 2026