Blog / Créer un package Laravel sur son environnement local

Image used for article Créer un package Laravel sur son environnement local

Créer un package Laravel sur son environnement local




TL;DR: Comment configurer un environnement de développement local pour tester vos classes ou utilitaires de package PHP dans un projet Laravel local.




Vous trouverez un projet Laravel d’exemple sur ce Github Repository.

Découvrez en plus sur Capsules ou X.




Il ne devrait pas vous surprendre d'apprendre que nous utilisons des centaines de packages lors du développement d'outils web. Pour les obtenir, il suffit de faire ses emplettes auprès d'un gestionnaire de packages, tel que Packagist, qui en compte 382 000 en octobre 2023.




Si vous souhaitez développer votre propre package, il est tout à fait légitime de vous demander comment le tester dans des conditions réelles. Publier le package sur Packagist en plein développement n'est pas une option. Une autre approche serait de l'intégrer dans un projet vierge sans utiliser Composer. la méthode de cet article se rapproche beaucoup plus d'une situation réelle, mais nécessite une préparation de l'environnement.



Créez un dossier qui servira de base pour votre package.


mkdir package




Création d’un fichier composer.json, qui constitue la base essentielle du package.



package/composer.json


{
    "name": "capsulescodes/package",
    "description": "Capsules Codes Package",
    "type": "library",
    "autoload": { "psr-4" : { "CapsulesCodes\\Package\\" : "src/" } }
}
  • name : Le nom doit être structuré avec l'entité à gauche et le nom du package à droite. Il est fortement recommandé d'utiliser un nom de package descriptif pour faciliter la recherche par les utilisateurs.
  • description : La description du package doit être claire et concise.
  • type : il existe 4 types library, project, metapackage et composer-plugin . le type library est le plus couramment utilisé. project représente un projet comme un modèle de framework.
  • autoload: C'est l'élément central de notre package, définissant un espace de noms pour accéder aux données situées à la racine du projet. Le protocole de spécification d'auto-chargement des classes à partir des chemins de fichiers est défini par PSR-4. C'est une étape indispensable. Veillez à ajouter les \\, en particulier à la fin de la phrase.




Il est conseillé de s'assurer que les informations du name correspondent au namespace. De plus, il est recommandé d'utiliser src comme nom de dossier à la racine du projet.



En outre, si vous exécutez composer init dans un dossier qui ne contient pas de fichier composer.json, un assistant vous guidera tout au long du processus de création de votre fichier composer.json.



Créez un dossier src à l'intérieur du dossier du package.



cd package
mkdir src
  • La disposition des dossiers n'a pas de réelle importance, mis à part leur proximité, tant pour vous que pour cet article.




Créez une classe PHP nommée Greeter contenant une fonction greet renvoyant la phrase Hello world!.



package/src/Greeter.php


<?php

namespace CapsulesCodes\Package;

class Greeter
{
    public static function greet() : string
    {
        return "Hello world!";
    }
}
  • Ne pas oublier d’indiquer le namespace. Autrement, la classe sera introuvable.




Il est maintenant possible de tester ce package. Pour cela il faut créer un environnement de test à l’aide d’un projet Laravel modèle.



Retour au dossier parent du package et création d’un projet Laravel faisant office de template de test.



cd ../
composer create-project laravel/laravel template
  • la commande composer create-project laravel/laravel template génère ici un 'type': 'project'.




Pour informer le template que notre package se trouve dans le même dossier parent , il est nécessaire d'ajouter deux informations au fichier composer.json.



template/composer.json


...
"minimum-stability": "dev",
"repositories": [ { "type" : "path", "url" : "../package" } ]
...
  • minimum-stability : Cette option permet l'installation du package via composer sans générer d'exception. Cela s'avère nécessaire lorsque le package n’est pas stable , en l’occurence, notre package est actuellement dev.
  • repositories : ce tableau permet d’ajouter des chemins d’accès vers d’autres dossiers auquel composer doit se référer pour trouver un package en local.
  • type : le type de dossier peut être composer , package , vcs ou path . L'option path permet d'utiliser localement un package, tandis que l'option vcs permet l'utilisation d'un package via un système de contrôle de version tel que Github.




Il est temps d’installer notre nouveau package.



cd template
composer require capsulescodes/package




Il est désormais répertorié dans les dépendances requises require.



template/composer.json


"require": {
	...
	"capsulescodes/package": "dev-main",
	...
}
  • Étant donné que le package est en cours de développement, la notion de dev-main est utilisée.




Tester via php artisan tinker.



php artisan tinker

> CapsulesCodes\Package\Greeter::greet()
= "Hello world!"




Ou modification du fichier web.php pour tester la classe statique Greeter.



package/routes/web.php


<?php

use Illuminate\Support\Facades\Route;
use CapsulesCodes\Package\Greeter;

Route::get( '/', fn() => dd( Greeter::greet() ) );
"Hello world!" // routes/web.php:7




L’environnement de travail est en place.



Il serait intéressant d’ajouter la méthode supplémentaire say() pour tester l’outil en temps réel.



package/src/Greeter.php


<?php

namespace CapsulesCodes\Package;

class Greeter
{
    public static function greet() : string
    {
        return "Hello world!";
    }

    public static function say( string $something ) : string
    {
        return $something;
    }
}




Tester via php artisan tinker. Il est probablement nécessaire de le relancer.



php artisan tinker

> CapsulesCodes\Package\Greeter::say( "That's a quick way to develop and test a package!" )
= "That's a quick way to develop and test a package!"




Ou modifier le fichier web.php pour tester la classe statique Greeter.



package/routes/web.php


<?php

use Illuminate\Support\Facades\Route;
use CapsulesCodes\Package\Greeter;

Route::get( '/', fn() => dd( Greeter::say( "That's a quick way to develop and test a package!" ) ) );


"That's a quick way to develop and test a package!"  // routes/web.php:7




À ce stade, tout est prêt pour développer un package PHP Framework agnostique. D'autres étapes sont nécessaires pour créer un package Laravel. Pour cet article, il est question de mettre en œuvre une commande php artisan greet qui appellera la classe statique Greeter.



Il est recommandé de suivre la structure de projet typique de Laravel lors de la création d'un package Laravel. Cela facilite la recherche d'informations pour ceux qui en ont le besoin.



Pour commencer, il est nécessaire de créer le GreetCommand en étendant la commande Illuminate\Console\Command propre à Laravel.



package/src/Commands/GreetCommand.php


<?php

namespace CapsulesCodes\Package\Console\Commands;

use Illuminate\Console\Command;
use CapsulesCodes\Package\Greeter;

class GreetCommand extends Command
{
    protected $signature = "greet";

		protected $description = "Greet people with a 'Hello world!'";

    public function handle()
    {
        dump( Greeter::greet() );
    }
}
  • La classe Illuminate\Console\Command de base de Laravel est utilisée comme extension.
  • La classe statique Greeter créée précédemment est utilisée dans la méthode handle(). Cependant, pour tester le package, vous pouvez simplement remplacer return Greeter::greet() par return "Hello world!"."




Pour que le projet modèle puisse reconnaître cette commande, il est nécessaire de le notifier à l'aide d'un ServiceProvider.



package/src/Providers/PackageServiceProvider


<?php

namespace CapsulesCodes\Package\Providers;

use Illuminate\Support\ServiceProvider;
use CapsulesCodes\Package\Console\Commands\GreetCommand;

class PackageServiceProvider extends ServiceProvider
{
    public function boot()
    {
        $this->commands( [ GreetCommand::class ] );
    }
}
  • La classe Illuminate\Support\ServiceProvider de base de Laravel est utilisée comme extension.
  • La commande GreetCommand nouvellement créée est ajoutée au tableau demandé par la méthode this->commands , permettant au projet template d’accéder à la commande.




Le package doit maintenant informer le projet modèle qu'un nouveau ServiceProvider est disponible à la découverte. Cela permet d’éviter son ajout manuel à la liste des ServiceProviders du fichier de configuration app.php.



package/composer.json


"extra" : { "laravel" : { "providers" : [ "CapsulesCodes\\Package\\Providers\\PackageServiceProvider" ] } },




Tester la commande php artisan greet.



php artisan greet

"Hello world!" // ../package/src/Console/Commands/GreetCommand.php:17




En cas de problème, il est conseillé d’exécuter la commande composer update pour recharger le package.



ou modification du fichier web.php pour tester la commande Artisan greet.



package/routes/web.php


<?php

use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Artisan;

Route::get( '/', fn() => Artisan::call( 'greet' ) );


"Hello world!" // routes/web.php:7



Et si vous souhaitez rendre votre GreetCommand accessible uniquement en mode console, ajoutez cette condition dans le PackageServiceProvider.



package/src/Providers/PackageServiceProvider.php


public function boot()
{
		if( $this->app->runningInConsole() ) $this->commands( [ GreetCommand::class ] );
}




Il est aussi possible d’implémenter un fichier de config, des migrations , des tests, des routes ou encore des views. Peut-être plus tard.




Ravi d’avoir pu aider !

v1.2.1

Icône XIcône Github