burger menu icon Web^ID
💬 Contact 💬 Contact
30 07 2025
retour à la liste des articles

Création d'un package avec Laravel

• écrit par [Web^ID]

marqueur jaune Default image alt

Un package Laravel peut être comparé à une boîte à outils réutilisable pour vos projets. Il vous permet d'exploiter une fonctionnalité utile sur plusieurs projets sans avoir à la recoder systématiquement. Les packages offrent également la possibilité de partager vos créations avec la communauté Laravel.

Cet article détaillera la procédure de création d'un package Laravel, en abordant sa structuration, la rédaction de tests, et sa publication sur Packagist.

Pourquoi créer un package Laravel ?

Créer un package Laravel offre plusieurs avantages :

  1. Réutilisabilité : Vous pouvez réutiliser le même code dans plusieurs projets sans avoir à le réécrire.

  2. Modularité : Les packages permettent de diviser votre application en modules indépendants, ce qui facilite la maintenance et les mises à jour.

  3. Partage : Vous pouvez partager vos packages avec la communauté Laravel, ce qui peut être bénéfique pour d'autres développeurs et pour votre propre réputation.

  4. Organisation : Les packages aident à organiser votre code de manière plus structurée et logique.

Étapes pour Créer un Package Laravel

Étape 1 : Créer le dossier de votre package

il existe deux façon de commencer la création de votre package :

  1. Créer dans un projet Laravel existant un dossier package à la racine

    mkdir packages/my-name/package-name

  2. Créer un dossier où vous voulez en dehors d’un projet Laravel

    mkdir package-name

Ensuite, il suffit de se rendre dans le dossier précédemment créer et l'initialiser en tant que dépôt Git : git init

Étape 2 : Initialisation de composer

La création d’un package nécessite d’avoir un composer.json. Ce fichier indiquera à Packagist ce qu'est ce paquet et ce qu'il doit exécuter.

Deux possibilités :

  1. Le faire à la main

  2. En ligne de commande : composer init

Comme nous construisons un package Laravel, la première chose dont nous aurons besoin est le package de support Laravel.
Il peut être installer via la commande : composer require illuminate/support

Le fichier doit ressembler à ceci :

{
    "name": "my-name/package-name",
    "description": "Description de mon package Laravel",
    "type": "library",
    "license": "MIT",
    "authors": [
        {
            "name": "Votre Nom",
            "email": "votre.email@example.com"        
        }
    ],
    "require": {
        "php": "^8.3",
        "illuminate/support": "^11.0"    
    },
    "require-dev": {},
    "autoload": {
        "psr-4": {
            "MyName\\PackageName\\": "src/"        
         }
    },
    "autoload-dev": {
        "psr-4": {
            "MyName\\PackageName\\Tests\\": "tests/"        
        }
    },
    "extra": {
        "laravel": {
            "providers": [
                "MyName\\PackageName\\Providers\\MonPackageServiceProvider"            
            ]
        }
    },
    "minimum-stability": "dev",
    "prefer-stable": true
}

Étape 3 : Création de notre fournisseur de services (Service Provider)

Ce fournisseur est le cœur de votre package, car il indique à Laravel comment charger le package et ce qui est disponible, telles que les vues, la configuration et les fichiers de localisation. Laravel détecte automatiquement les fournisseurs de services dans le dossier src. Pour ce faire, il faut créer la classe src/MonPackageServiceProvider.php.

Ce fichier contient deux méthodes :

  1. register() : Enregistrer les services du package

  2. boot() : Configuration et initialisation de tous les services du package

Les packages doivent souvent publier des ressources telles que des fichiers de configuration, des vues et des migrations vers l'application principale. Lorsque la commande Laravel vendor:publish sera lancée, les fichiers seront copié à l'emplacement spécifié.

<?php

declare(strict_types=1);

namespace MyName\PackageName\Providers;

use Illuminate\Support\ServiceProvider;
use MonVendor\MonPackage\Commands\MonCommande;

class MonPackageServiceProvider extends ServiceProvider
{
    public function boot(): void 
    {
        // Publication des fichiers de configuration        
        $this->publishes([
            __DIR__.'/../../config/mon-package.php' => config_path('mon-package.php'),
        ], 'config');

        // Publication des vues        
        $this->publishes([
            __DIR__.'/../../resources/views' => resource_path('views/vendor/mon-package'),
        ], 'views');

        // Publication des migrations        
        $this->publishes([
            __DIR__.'/../../database/migrations' => database_path('migrations'),
        ], 'migrations');

        // Chargement des vues        
        $this->loadViewsFrom(__DIR__.'/../../resources/views', 'mon-package');

        // Chargement des migrations        
        $this->loadMigrationsFrom(__DIR__.'/../../database/migrations');

        // Chargement des routes        
        $this->loadRoutesFrom(__DIR__.'/../../routes/web.php');

        // Chargement des traductions        
        $this->loadTranslationsFrom(__DIR__.'/../../resources/lang', 'mon-package');

        // Enregistrement des commandes Artisan        
        if ($this->app->runningInConsole()) {
            $this->commands([
                MaCommande::class,
            ]);
        }
    }

    public function register(): void 
    {
        // Fusion de la configuration        
        $this->mergeConfigFrom(
            __DIR__.'/../../config/mon-package.php',
            'mon-package'
        );

        // Enregistrement des services dans le conteneur        
        $this->app->singleton('mon-package', function ($app) {
            return new \MyName\PackageName\MonPackage();
        });
    }
}

Étape 4 : La configuration du Package

Créez un fichier de configuration dans le dossier src/config/mon-package.php :

<?php

return [
    /*
    |--------------------------------------------------------------------------
    | Configuration de mon package
    |--------------------------------------------------------------------------
    |
    | Ici vous pouvez définir toutes les options de configuration
    | pour votre package.
    |
    */    
    
    'key' => 'value',
];

Étape 5 : Création des Vues

Créez des vues pour votre package dans resources/views/welcome.blade.php :

@extends('packageName::layouts.app')

@section('title', 'Bienvenue dans Mon Package' )

@section('content')
    <section class="section">        
       <div class="container">            
          <p>{{ $message ?? "Message par défaut" }}</p>        
       </div>    
    </section>
@endsection

Étape 6 : Création des routes et contrôleurs

Créez le fichier de routes routes/web.php :

<?php

use Illuminate\Support\Facades\Route;
use MyName\PackageName\Controllers\MonPackageController;

Route::prefix('package-name')
    ->name('packageName.')
    ->middleware('web')
    ->group(function () {
        Route::get('/', [MonPackageController::class, 'index'])->name('index');
    });

Le contrôleur correspondant src/Controllers/MonPackageController.php :

<?php

declare(strict_types=1);

namespace MyName\PackageName\Controllers;

use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\View\View;

class MonPackageController extends Controller
{
    public function index(): View
    {
        return view('packageName::welcome', [
            'message' => 'Votre package fonctionne parfaitement !'
        ]);
    }
}

Étape 7 : Les tests

C'est une étape très importante. Pour initialiser une suite de tests au sein de notre package, la méthode la plus simple consiste à utiliser pestPHP et Testbench.

composer require pestphp/pest --dev --with-all-dependencies

composer require --dev orchestra/testbench

Après l'installation de pestPHP, il faut exécutez la commande : ./vendor/bin/pest --init
Cela générera le fichier phpunit.xml et un fichier tests/Pest.php permettant de contrôler et d'étendre Pest.

Pour les tests du package, il va falloir créer un fichier tests/PackageTestCase.php afin de pouvoir contrôler nos tests plus facilement et de pouvoir enregistrer notre fournisseur de services pour garantir son chargement dans l'application de test.

declare(strict_types=1);
 
namespace MyName\PackageName\Tests;
 
use MyName\PackageName\PackageServiceProvider;
use Orchestra\Testbench\TestCase;
 
class PackageTestCase extends TestCase
{
    protected function getPackageProviders($app): array    
    {
        return [
            PackageServiceProvider::class,
        ];
    }
}

Il est important de ne pas oublier de modifier le fichier tests/Pest.php pour utiliser notre fichier PackageTestCase dans nos tests :

declare(strict_types=1);
 
use MyName\PackageName\Tests\PackageTestCase;
  
uses(PackageTestCase::class)->in(__DIR__);

Pour la rédaction des tests, je vous invite à directement aller voir la documentation de pest : https://pestphp.com/docs/writing-tests

Étape 8 : La qualité de code

Chez Web^ID la qualité de code est également une étape très importante.

Nous allons commencer avec le style de code avec Laravel Pint : composer require --dev laravel/pint
Pint ne nécessite aucune configuration. Cependant, si vous souhaitez personnaliser les préréglages, les règles ou les dossiers inspectés, vous pouvez le faire en créant un fichier pint.json :

{
  "preset": "laravel"
}

En exécutant la commande pint ./vendor/bin/pint cela va corriger tous les problèmes de style de code qui ne sont pas conformes. Si vous le souhaitez Pint peut s'exécuter en mode parallèle : ./vendor/bin/pint --parallel .

Après Pint, nous avons Larastan qui est un outil d'analyse statique et permet de trouver des bugs dans votre application Laravel avant même qu'elle ne soit exécutée.

composer require --dev larastan/larastan

Pour configurer Larastan, il faut créer un fichier phpstan.neon.dist :

parameters:
    level: max
    paths:
        - config
        - database
        - resources
        - routes
        - src

   tmpDir: build/phpstan

Pour lancer l'analyse du code avec Larastan, il suffit d'utiliser la commande : php artisan code:analyse

Étape 9 : Documentation

Documenter correctement son package est essentiel :

  • Expliquer votre package

  • Donner les éléments requis pour l'utilisation du package

  • Donner la marche à suivre pour l'installation

  • ....

Étape 10 : Installation

Pour utiliser votre package en local dans un projet Laravel, vous avez plusieurs possibilité, je vais vous en donner deux :

  1. Votre package se trouve déjà dans votre projet Laravel, il faut ajouter dans le composer.json de votre projet :

"repositories": [
    {
        "type": "path",
        "url": "./packages/my-name/package-name"    
    }
],
"require": {
    "my-name/package-name": "*"
}
  1. Votre package se trouve dans un autre dossier que votre projet Laravel.

    Il vous suffit de faire un lien symbolique dans votre projet Laravel : ln -s /chemin/vers/mon-package /chemin/vers/votre/projet/laravel/vendor/mon-vendeur/mon-package

    Et de changer le composer.json comme haut dessus.

A la fin, votre package devrait avoir la structure suivante :

package-name/
├── src/
│   ├── Commands/
│   ├── Controllers/
│   ├── Models/
│   ├── Middleware/
│   ├── MonPackageServiceProvider.php
│   └── MonPackage.php
├── config/
│   └── mon-package.php
├── database/
│   ├── migrations/
│   └── seeders/
├── resources/
│   ├── views/
│   └── lang/
├── routes/
│   ├── web.php
│   └── api.php
├── tests/
├── vendor/
├── workbench/
├── .gitignore
├── composer.json
├── phpstan.neon.dist
├── pint.json
└── README.md

Publier votre package sur Packagist

Préparation

  1. Si cela n'a pas été fait au début, initialiser votre dossier de package en tant que dépôt Git : git init

  2. Ajoutez tous vos fichiers et committez

  3. (Optionnel) Créez des tags de version :

git tag v1.0.0
git push origin v1.0.0

Utilisez le versioning sémantique (MAJOR.MINOR.PATCH) :

  • MAJOR : changements incompatibles

  • MINOR : nouvelles fonctionnalités compatibles

  • PATCH : corrections de bugs

Publication

  1. Allez sur Packagist.org

  2. Connectez-vous avec votre compte GitHub

  3. Soumettez l'URL de votre repository

  4. Packagist synchronisera automatiquement les nouvelles versions si vous avez ajouter des tags

Conclusion

La création d'un package Laravel demande une planification soignée mais offre de nombreux avantages : réutilisabilité, maintenabilité et possibilité de contribuer à la communauté.

Pour vous aider dans cette démarche, il est conseillé d'explorer les packages Laravel déjà disponibles sur Packagist. Cela vous permettra de vous familiariser avec les bonnes pratiques et les modèles fréquemment utilisés au sein de l'écosystème Laravel.

filaire image filaire image
Vous souhaitez démarrer rapidement ?
Besoin d'accompagnement ?

Vous voulez en savoir plus ou vous souhaitez nous parler de votre projet ?
Nous sommes à votre disposition !