
Ecrire un package Laravel
DRY ! Oui tu as raison c’est un acronyme : Don’t Repeat Yourself - Ne te répète pas. L’idée d’un package est de contenir du code qui répond à un besoin précis et qui pourra être utiliser dans diverses applications.
Création d’un package Laravel
Un package Laravel démarre avec 2 fichiers :
- un fichier
composer.json
qui renseignera la manière de charger tes classes (oui je parle de PSR-4 là) - une classe
ServiceProvider
qui sert à l’initialisation de ton package.
Composer.json
Voilà à quoi doit ressembler le fichier composer.json. Tu noteras que j’ai volontairement omis les tests unitaires dans le fichier. Oui c’est volontaire, j’espère sortir un article dédié sur le sujet bientôt ;)
{
"name": "fabpl/package",
"description": "My awesome package",
"homepage": "https://github.com/fabpl/package",
"license": "MIT",
"type": "library",
"authors": [
{
"name": "Fabrice PLANCHETTE",
"role": "Developer"
}
],
"require": {
"php": "^7.1",
"illuminate/support": "^6.0"
},
"autoload": {
"psr-4": {
"Fabpl\\Package\\": "src"
}
},
"config": {
"sort-packages": true
},
"extra": {
"laravel": {
"providers": [
"Fabpl\\Package\\PackageServiceProvider"
]
}
}
}
Service Provider
Laravel se charge tout seul de “découvrir” notre service provider (si si, c’est écrit dans la documentation), reste plus qu’à écrire son contenu :
<?php
namespace Fabpl\Package;
use Illuminate\Support\ServiceProvider;
class PackageServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*/
public function boot()
{
//
}
/**
* Register the application services.
*/
public function register()
{
//
}
}
Bah, t’as rien mis dans tes méthodes boot() et register ? C’est une blague ? Tu serais pas impatient toi ? Attends, je te détaille ça.
Déjà il faut comprendre la différence. Une fois que tous les services providers ait été enregistrés (registered), ils vont être “booter”.
Boot
Tu y mettras notamment ce qui doit être “charger”. Fichiers de traduction, de migrations, les vues et… les routes.
Je te donne quelques exemples :
$this->loadTranslationsFrom(__DIR__.'/../resources/lang', 'package');
$this->loadViewsFrom(__DIR__.'/../resources/views', 'package');
$this->loadMigrationsFrom(__DIR__.'/../database/migrations');
$this->loadRoutesFrom(__DIR__.'/routes.php');
Tu vas également renseigner ce qui peut être “publier”, c’est à dire copier vers l’application.
if ($this->app->runningInConsole()) {
$this->publishes([
__DIR__.'/../config/config.php' => config_path('package.php'),
], 'config');
// Publishing the views.
$this->publishes([
__DIR__.'/../resources/views' => resource_path('views/vendor/package'),
], 'views');
// Publishing assets.
$this->publishes([
__DIR__.'/../resources/assets' => public_path('vendor/package'),
], 'assets');
// Publishing the translation files.
$this->publishes([
__DIR__.'/../resources/lang' => resource_path('lang/vendor/package'),
], 'lang');
}
Et le dernier truc, c’est si tu as des commandes artisan à enregister :
if ($this->app->runningInConsole()) {
$this->commands([
FooCommand::class,
]);
}
Register
Le 1er truc à faire c’est de merger la config par défaut que tu as mis dans ton package, et celle que pourra surcharger le développement dans son application.
$this->mergeConfigFrom(__DIR__.'/../config/config.php', 'package');
C’est également dans cette méthode que tu vas enregistrer tes singletons.
Mais je t’en ai trop dit, faut aller voir la documentation sur Laravel maintenant.
Ah si j’oubliais ! Le top pour apprendre c’est de fouiller dans les packages des autres. y’a notamment Spatie qui en fait énormement de package pour Laravel.