Sviluppo di Package

Introduzione

I package sono il modo principale per aggiungere funzionalità a Laravel. I package possono essere qualsiasi cosa, da un ottimo modo per lavorare con le date come Carbon oppure un package che ti permette di associare file ai modelli Eloquent come Laravel Media Library di Spatie.

Esistono diversi tipi di package. Alcuni package sono stand-alone, il che significa che funzionano con qualsiasi framework PHP. Carbon e Pest sono esempi di package stand-alone. Qualsiasi di questi package può essere usato con Laravel richiedendoli nel tuo file composer.json.

D’altra parte, altri package sono specificamente pensati per l’uso con Laravel. Questi package possono avere route, controller, viste e configurazioni pensate per migliorare un’applicazione Laravel. Questa guida si concentra principalmente sullo sviluppo di quei package che sono specifici per Laravel.

Una Nota sulle Facades

Quando scrivi un’applicazione Laravel, generalmente non fa differenza se usi contratti o facades poiché entrambi offrono livelli di testabilità sostanzialmente uguali. Tuttavia, quando sviluppi package, il tuo package normalmente non avrà accesso a tutti gli helper di testing di Laravel. Se vuoi poter scrivere i test del tuo package come se fosse installato in una tipica applicazione Laravel, puoi utilizzare il package Orchestral Testbench.

Scoperta dei Package

Il file bootstrap/providers.php di un’applicazione Laravel contiene l’elenco dei service provider che Laravel deve caricare. Tuttavia, invece di far aggiungere manualmente il tuo service provider agli utenti, puoi definirlo nella sezione extra del file composer.json del tuo package, così Laravel lo caricherà automaticamente. Oltre ai service provider, puoi anche elencare eventuali facades che vuoi registrare:

"extra": {
    "laravel": {
        "providers": [
            "Barryvdh\\Debugbar\\ServiceProvider"
        ],
        "aliases": {
            "Debugbar": "Barryvdh\\Debugbar\\Facade"
        }
    }
},

Una volta configurato il tuo package per la scoperta, Laravel registrerà automaticamente i suoi service provider e facades durante l’installazione, creando un’esperienza di installazione comoda per gli utenti del tuo package.

Esclusione dalla Scoperta dei Package

Se utilizzi un package e vuoi disabilitare la scoperta automatica per esso, puoi elencare il nome del package nella sezione extra del file composer.json della tua applicazione:

"extra": {
    "laravel": {
        "dont-discover": [
            "barryvdh/laravel-debugbar"
        ]
    }
},

Puoi disabilitare la scoperta automatica per tutti i package utilizzando il carattere * all’interno della direttiva dont-discover della tua applicazione:

"extra": {
    "laravel": {
        "dont-discover": [
            "*"
        ]
    }
},

Service Providers

I Service provider sono il punto di connessione tra il tuo package e Laravel. Un service provider è responsabile per il binding delle componenti nel service container di Laravel e per informare Laravel su dove caricare le risorse del package come viste, configurazioni e file di lingua.

Un service provider estende la classe Illuminate\Support\ServiceProvider e contiene due metodi: register e boot. La classe base ServiceProvider si trova nel package Composer illuminate/support, che dovresti aggiungere alle dipendenze del tuo package. Per saperne di più sulla struttura e lo scopo dei service providers, consulta la loro documentazione.

Risorse

Configurazione

Di solito, dovrai pubblicare il file di configurazione del tuo package nella directory config dell’applicazione. Questo permetterà agli utenti del tuo package di sovrascrivere facilmente le opzioni di configurazione predefinite. Per consentire la pubblicazione dei tuoi file di configurazione, chiama il metodo publishes dal metodo boot del tuo service provider:

/**
 * Bootstrap any package services.
 */
public function boot(): void
{
    $this->publishes([
        __DIR__.'/../config/courier.php' => config_path('courier.php'),
    ]);
}

Ora, quando gli utenti del tuo package eseguono il comando vendor:publish di Laravel, il tuo file verrà copiato nella posizione di pubblicazione specificata. Una volta che la tua configurazione è stata pubblicata, i suoi valori possono essere accessi come qualsiasi altro file di configurazione:

$value = config('courier.option');

Non dovresti definire closure nei tuoi file di configurazione. Non possono essere serializzate correttamente quando gli utenti eseguono il comando config:cache di Artisan.

Configurazione Predefinita del Package

Puoi anche unire il file di configurazione del tuo package con la copia pubblicata dell’applicazione. Questo permetterà ai tuoi utenti di definire solo le opzioni che desiderano sovrascrivere nella copia pubblicata del file di configurazione. Per unire i valori del file di configurazione, usa il metodo mergeConfigFrom all’interno del metodo register del tuo service provider.

Il metodo mergeConfigFrom accetta il percorso del file di configurazione del tuo package come primo argomento e il nome della copia del file di configurazione dell’applicazione come secondo argomento:

    /**
     * Register any application services.
     */
    public function register(): void
    {
        $this->mergeConfigFrom(
            __DIR__.'/../config/courier.php', 'courier'
        );
    }

Questo metodo unisce solo il primo livello dell’array di configurazione. Se i tuoi utenti definiscono parzialmente un array di configurazione multidimensionale, le opzioni mancanti non verranno unite.

Routes

Se il tuo package contiene routes, puoi caricarle usando il metodo loadRoutesFrom. Questo metodo verificherà automaticamente se le routes dell’applicazione sono cache e non caricherà il file delle routes se le routes sono già state cache:

    /**
     * Bootstrap any package services.
     */
    public function boot(): void
    {
        $this->loadRoutesFrom(__DIR__.'/../routes/web.php');
    }

Migrazioni

Se il tuo package contiene migrazioni del database, puoi usare il metodo publishesMigrations per informare Laravel che la directory o il file indicato contiene migrazioni. Quando Laravel pubblica le migrazioni, aggiornerà automaticamente il timestamp nel nome del file per riflettere la data e l’ora correnti:

/**
 * Bootstrap di qualsiasi servizio del package.
 */
public function boot(): void
{
    $this->publishesMigrations([
        __DIR__.'/../database/migrations' => database_path('migrations'),
    ]);
}

File di Lingua

Se il tuo package contiene file di lingua, puoi usare il metodo loadTranslationsFrom per informare Laravel su come caricarli. Ad esempio, se il tuo package si chiama courier, dovresti aggiungere quanto segue al metodo boot del tuo service provider:

    /**
     * Bootstrap any package services.
     */
    public function boot(): void
    {
        $this->loadTranslationsFrom(__DIR__.'/../lang', 'courier');
    }

Le linee di traduzione del package vengono riferite usando la convenzione di sintassi package::file.line. Quindi, puoi caricare la linea welcome del package courier dal file messages in questo modo:

    echo trans('courier::messages.welcome');

Puoi registrare i file di traduzione JSON per il tuo package usando il metodo loadJsonTranslationsFrom. Questo metodo accetta il percorso della directory che contiene i file di traduzione JSON del tuo package:

/**
 * Bootstrap any package services.
 */
public function boot(): void
{
    $this->loadJsonTranslationsFrom(__DIR__.'/../lang');
}

Pubblicazione dei File di Lingua

Se desideri pubblicare i file di lingua del tuo package nella directory lang/vendor dell’applicazione, puoi usare il metodo publishes del service provider. Il metodo publishes accetta un array di percorsi del package e le relative destinazioni di pubblicazione. Ad esempio, per pubblicare i file di lingua del package courier, puoi fare così:

    /**
     * Bootstrap any package services.
     */
    public function boot(): void
    {
        $this->loadTranslationsFrom(__DIR__.'/../lang', 'courier');

        $this->publishes([
            __DIR__.'/../lang' => $this->app->langPath('vendor/courier'),
        ]);
    }

Ora, quando gli utenti del tuo package eseguono il comando Artisan vendor:publish di Laravel, i file di lingua del tuo package verranno pubblicati nella destinazione specificata.

View

Per registrare le views del tuo package in Laravel, devi indicare a Laravel dove si trovano le view. Puoi farlo usando il metodo loadViewsFrom del service provider. Il metodo loadViewsFrom accetta due argomenti: il percorso dei tuoi template di view e il nome del tuo package. Ad esempio, se il nome del tuo package è courier, aggiungeresti il seguente codice al metodo boot del tuo service provider:

    /**
     * Bootstrap any package services.
     */
    public function boot(): void
    {
        $this->loadViewsFrom(__DIR__.'/../resources/views', 'courier');
    }

Le view del package vengono riferite usando la convenzione di sintassi package::view. Quindi, una volta che il percorso delle view è registrato in un service provider, puoi caricare la view dashboard dal package courier in questo modo:

    Route::get('/dashboard', function () {
        return view('courier::dashboard');
    })

Sovrascrivere le View del Package

Quando usi il metodo loadViewsFrom, Laravel registra due posizioni per le tue view: la cartella resources/views/vendor dell’applicazione e la directory che specifichi. Ad esempio, utilizzando il package courier, Laravel controllerà prima se una versione personalizzata della view è stata inserita nella cartella resources/views/vendor/courier dallo sviluppatore. Se la view non è stata personalizzata, Laravel cercherà nella directory delle view del package che hai specificato nella chiamata a loadViewsFrom. Questo permette agli utenti del package di personalizzare o sovrascrivere facilmente le view del tuo package.

Pubblicare le View

Se vuoi rendere disponibili le tue view per la pubblicazione nella directory resources/views/vendor dell’applicazione, puoi usare il metodo publishes del service provider. Il metodo publishes accetta un array di percorsi delle view del package e le loro destinazioni di pubblicazione desiderate:

/**
 * Bootstrap the package services.
 */
public function boot(): void
{
    $this->loadViewsFrom(__DIR__.'/../resources/views', 'courier');

    $this->publishes([
        __DIR__.'/../resources/views' => resource_path('views/vendor/courier'),
    ]);
}

Ora, quando gli utenti del tuo package eseguono il comando Artisan vendor:publish di Laravel, le view del tuo package saranno copiate nella destinazione di pubblicazione specificata.

Componenti delle View

Se stai creando un package che utilizza i componenti Blade o posizioni i componenti in directory non convenzionali, dovrai registrare manualmente la tua classe componente e il suo alias di tag HTML in modo che Laravel sappia dove trovare il componente. Solitamente dovresti registrare i tuoi componenti nel metodo boot del service provider del tuo package:

use Illuminate\Support\Facades\Blade;
use VendorPackage\View\Components\AlertComponent;

/**
 * Avvia i servizi del tuo package.
 */
public function boot(): void
{
    Blade::component('package-alert', AlertComponent::class);
}

Una volta registrato il tuo componente, puoi renderizzarlo usando il suo alias di tag:

<x-package-alert/>

Caricamento Automatico dei Componenti del Package

In alternativa, puoi usare il metodo componentNamespace per caricare automaticamente le classi dei componenti per convenzione. Ad esempio, un package Nightshade potrebbe avere i componenti Calendar e ColorPicker che si trovano nello spazio dei nomi Nightshade\Views\Components:

use Illuminate\Support\Facades\Blade;

/**
 * Bootstrap your package's services.
 */
public function boot(): void
{
    Blade::componentNamespace('Nightshade\\Views\\Components', 'nightshade');
}

Questo permetterà di usare i componenti del package tramite il loro namespace del fornitore utilizzando la sintassi package-name:::

<x-nightshade::calendar />
<x-nightshade::color-picker />

Blade rileverà automaticamente la classe associata a questo componente applicando il pascal-casing al nome del componente. Anche le sottocartelle sono supportate usando la notazione con i "punti".

Componenti Anonimi

Se il tuo package contiene componenti anonimi, devono essere posizionati nella directory components all’interno della directory "views" del tuo package (come specificato dal metodo loadViewsFrom). Successivamente, puoi renderli anteponendo al nome del componente lo spazio dei nomi delle view del package:

<x-courier::alert />

Comando "About" di Artisan

Il comando about integrato di Artisan di Laravel fornisce una panoramica dell’ambiente e della configurazione dell’applicazione. I package possono aggiungere informazioni aggiuntive all’output di questo comando tramite la classe AboutCommand. Di solito, queste informazioni vengono aggiunte dal metodo boot del provider di servizio del tuo package:

use Illuminate\Foundation\Console\AboutCommand;

/**
 * Bootstrap any application services.
 */
public function boot(): void
{
    AboutCommand::add('My Package', fn () => ['Version' => '1.0.0']);
}

Comandi

Per registrare i comandi Artisan del tuo package con Laravel, puoi utilizzare il metodo commands. Questo metodo si aspetta un array di nomi delle classi dei comandi. Una volta registrati i comandi, puoi eseguirli utilizzando l’Artisan CLI:

use Courier\Console\Commands\InstallCommand;
use Courier\Console\Commands\NetworkCommand;

/**
 * Bootstrap any package services.
 */
public function boot(): void
{
    if ($this->app->runningInConsole()) {
        $this->commands([
            InstallCommand::class,
            NetworkCommand::class,
        ]);
    }
}

Comandi di Ottimizzazione

Il comando optimize di Laravel memorizza nella cache la configurazione, gli eventi, le rotte e le viste dell’applicazione. Utilizzando il metodo optimizes, puoi registrare i comandi Artisan del tuo package che devono essere eseguiti quando vengono eseguiti i comandi optimize e optimize:clear:

/**
 * Avviare qualsiasi servizio del package.
 */
public function boot(): void
{
    if ($this->app->runningInConsole()) {
        $this->optimizes(
            optimize: 'package:optimize',
            clear: 'package:clear-optimizations',
        );
    }
}

Asset Pubblici

Il tuo package potrebbe includere asset come JavaScript, CSS e immagini. Per pubblicare questi asset nella directory public dell’applicazione, utilizza il metodo publishes del service provider. In questo esempio, aggiungeremo anche un tag di gruppo asset public, che può essere usato per pubblicare facilmente gruppi di asset correlati:

/**
 * Bootstrap any package services.
 */
public function boot(): void
{
    $this->publishes([
        __DIR__.'/../public' => public_path('vendor/courier'),
    ], 'public');
}

Ora, quando gli utenti del tuo package eseguono il comando vendor:publish, i tuoi asset verranno copiati nella posizione di pubblicazione specificata. Poiché gli utenti solitamente devono sovrascrivere gli asset ogni volta che il package viene aggiornato, puoi usare il flag --force:

php artisan vendor:publish --tag=public --force

Pubblicare Gruppi di File

Potresti voler pubblicare gruppi di asset e risorse del package separatamente. Ad esempio, potresti consentire ai tuoi utenti di pubblicare i file di configurazione del tuo package senza dover pubblicare gli asset del package. Puoi fare questo "taggandoli" quando chiami il metodo publishes dal service provider del package. Ad esempio, usiamo i tag per definire due gruppi di pubblicazione per il package courier (courier-config e courier-migrations) nel metodo boot del service provider del package:

    /**
     * Bootstrap any package services.
     */
    public function boot(): void
    {
        $this->publishes([
            __DIR__.'/../config/package.php' => config_path('package.php')
        ], 'courier-config');

        $this->publishesMigrations([
            __DIR__.'/../database/migrations/' => database_path('migrations')
        ], 'courier-migrations');
    }

Ora i tuoi utenti possono pubblicare questi gruppi separatamente facendo riferimento al loro tag quando eseguono il comando vendor:publish:

php artisan vendor:publish --tag=courier-config
Lascia un commento

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *