はじめに
パッケージは、Laravelに機能を追加するための主要な方法です。パッケージは、Carbonのような日付を扱うための優れた方法や、SpatieのLaravel Media LibraryのようにEloquentモデルにファイルを関連付けることを可能にするパッケージなど、さまざまなものがあります。
パッケージには異なる種類があります。一部のパッケージはスタンドアロンであり、任意のPHPフレームワークで動作します。CarbonやPestはスタンドアロンパッケージの例です。これらのパッケージは、composer.json
ファイルで要求することによってLaravelで使用できます。
一方、他のパッケージはLaravel専用に設計されています。これらのパッケージには、Laravelアプリケーションを強化するために特に意図されたルート、コントローラー、ビュー、および設定が含まれている場合があります。このガイドは、主にLaravel特有のパッケージの開発をカバーします。
ファサードに関する注意
Laravelアプリケーションを書く際、契約やファサードを使用するかどうかは一般的に重要ではありません。なぜなら、どちらも本質的に同等のテスト可能性を提供するからです。しかし、パッケージを書く際には、通常、パッケージはLaravelのすべてのテストヘルパーにアクセスできません。パッケージのテストを、パッケージが通常のLaravelアプリケーション内にインストールされているかのように書きたい場合は、Orchestral Testbenchパッケージを使用できます。
パッケージの発見
Laravelアプリケーションのbootstrap/providers.php
ファイルには、Laravelによって読み込まれるべきサービスプロバイダーのリストが含まれています。しかし、ユーザーに手動でサービスプロバイダーをリストに追加させる代わりに、パッケージのcomposer.json
ファイルのextra
セクションでプロバイダーを定義することで、Laravelによって自動的に読み込まれるようにできます。サービスプロバイダーに加えて、登録したいファサードをリストすることもできます:
"extra": {
"laravel": {
"providers": [
"Barryvdh\\Debugbar\\ServiceProvider"
],
"aliases": {
"Debugbar": "Barryvdh\\Debugbar\\Facade"
}
}
},
パッケージが発見のために構成されると、Laravelはインストール時に自動的にそのサービスプロバイダーとファサードを登録し、パッケージのユーザーにとって便利なインストール体験を提供します。
パッケージの発見を無効にする
パッケージの消費者であり、パッケージの発見を無効にしたい場合は、アプリケーションのcomposer.json
ファイルのextra
セクションにパッケージ名をリストすることができます:
"extra": {
"laravel": {
"dont-discover": [
"barryvdh/laravel-debugbar"
]
}
},
アプリケーションのdont-discover
ディレクティブ内で*
文字を使用して、すべてのパッケージの発見を無効にすることもできます:
"extra": {
"laravel": {
"dont-discover": [
"*"
]
}
},
サービスプロバイダー
サービスプロバイダーは、パッケージとLaravelの接続ポイントです。サービスプロバイダーは、Laravelのサービスコンテナに物事をバインドし、ビュー、設定、言語ファイルなどのパッケージリソースをどこから読み込むかをLaravelに通知する責任があります。
サービスプロバイダーはIlluminate\Support\ServiceProvider
クラスを拡張し、register
とboot
の2つのメソッドを含みます。基本のServiceProvider
クラスはilluminate/support
Composerパッケージにあり、これを自分のパッケージの依存関係に追加する必要があります。サービスプロバイダーの構造と目的について詳しく知りたい場合は、そのドキュメントを確認してください。
リソース
設定
通常、パッケージの設定ファイルをアプリケーションのconfig
ディレクトリに公開する必要があります。これにより、パッケージのユーザーはデフォルトの設定オプションを簡単に上書きできます。設定ファイルを公開できるようにするには、サービスプロバイダーのboot
メソッドからpublishes
メソッドを呼び出します:
/**
* Bootstrap any package services.
*/
public function boot(): void
{
$this->publishes([
__DIR__.'/../config/courier.php' => config_path('courier.php'),
]);
}
これで、パッケージのユーザーがLaravelのvendor:publish
コマンドを実行すると、指定された公開場所にファイルがコピーされます。設定が公開された後、その値は他の設定ファイルと同様にアクセスできます:
$value = config('courier.option');
設定ファイルにクロージャを定義してはいけません。ユーザーがconfig:cache
Artisanコマンドを実行するときに正しくシリアライズできません。
デフォルトのパッケージ設定
自分のパッケージ設定ファイルをアプリケーションの公開コピーとマージすることもできます。これにより、ユーザーは公開された設定ファイルのコピーで実際に上書きしたいオプションのみを定義できます。設定ファイルの値をマージするには、サービスプロバイダーのregister
メソッド内でmergeConfigFrom
メソッドを使用します。
``````php
/**
* Register any application services.
*/
public function register(): void
{
$this->mergeConfigFrom(
__DIR__.'/../config/courier.php', 'courier'
);
}
`
このメソッドは、設定配列の最初のレベルのみをマージします。ユーザーが多次元設定配列を部分的に定義した場合、欠落しているオプションはマージされません。
ルート
パッケージにルートが含まれている場合、loadRoutesFrom
メソッドを使用してそれらを読み込むことができます。このメソッドは、アプリケーションのルートがキャッシュされているかどうかを自動的に判断し、ルートがすでにキャッシュされている場合はルートファイルを読み込みません:
/**
* Bootstrap any package services.
*/
public function boot(): void
{
$this->loadRoutesFrom(__DIR__.'/../routes/web.php');
}
マイグレーション
パッケージにデータベースマイグレーションが含まれている場合、publishesMigrations
メソッドを使用してLaravelに指定されたディレクトリまたはファイルがマイグレーションを含むことを通知できます。Laravelがマイグレーションを公開すると、ファイル名内のタイムスタンプが現在の日付と時刻を反映するように自動的に更新されます:
/**
* Bootstrap any package services.
*/
public function boot(): void
{
$this->publishesMigrations([
__DIR__.'/../database/migrations' => database_path('migrations'),
]);
}
言語ファイル
パッケージに言語ファイルが含まれている場合、loadTranslationsFrom
メソッドを使用してLaravelにそれらを読み込む方法を通知できます。たとえば、パッケージの名前がcourier
の場合、サービスプロバイダーのboot
メソッドに次のように追加する必要があります:
/**
* Bootstrap any package services.
*/
public function boot(): void
{
$this->loadTranslationsFrom(__DIR__.'/../lang', 'courier');
}
パッケージの翻訳行は、package::file.line
構文規約を使用して参照されます。したがって、messages
ファイルからwelcome
行を次のように読み込むことができます:
echo trans('courier::messages.welcome');
``````php
/**
* Bootstrap any package services.
*/
public function boot(): void
{
$this->loadJsonTranslationsFrom(__DIR__.'/../lang');
}
`
言語ファイルの公開
パッケージの言語ファイルをアプリケーションのlang/vendor
ディレクトリに公開したい場合は、サービスプロバイダーのpublishes
メソッドを使用できます。publishes
メソッドは、パッケージパスとその希望する公開場所の配列を受け取ります。たとえば、courier
パッケージの言語ファイルを公開するには、次のようにします:
/**
* Bootstrap any package services.
*/
public function boot(): void
{
$this->loadTranslationsFrom(__DIR__.'/../lang', 'courier');
$this->publishes([
__DIR__.'/../lang' => $this->app->langPath('vendor/courier'),
]);
}
これで、パッケージのユーザーがLaravelのvendor:publish
Artisanコマンドを実行すると、パッケージの言語ファイルが指定された公開場所に公開されます。
ビュー
パッケージのビューをLaravelに登録するには、Laravelにビューの場所を知らせる必要があります。サービスプロバイダーのloadViewsFrom
メソッドを使用してこれを行うことができます。loadViewsFrom
メソッドは、ビューのテンプレートへのパスとパッケージの名前の2つの引数を受け取ります。たとえば、パッケージの名前がcourier
の場合、サービスプロバイダーのboot
メソッドに次のように追加します:
/**
* Bootstrap any package services.
*/
public function boot(): void
{
$this->loadViewsFrom(__DIR__.'/../resources/views', 'courier');
}
パッケージのビューは、package::view
構文規約を使用して参照されます。したがって、サービスプロバイダーにビューのパスが登録されると、次のようにdashboard
ビューをcourier
パッケージから読み込むことができます:
Route::get('/dashboard', function () {
return view('courier::dashboard');
});
パッケージビューの上書き
loadViewsFrom
メソッドを使用すると、Laravelは実際にビューのために2つの場所を登録します: アプリケーションのresources/views/vendor
ディレクトリと指定したディレクトリです。したがって、courier
パッケージを例にすると、Laravelは最初に開発者によってresources/views/vendor/courier
ディレクトリにカスタムバージョンのビューが配置されているかどうかを確認します。次に、ビューがカスタマイズされていない場合、LaravelはloadViewsFrom
への呼び出しで指定したパッケージビューのディレクトリを検索します。これにより、パッケージユーザーはパッケージのビューをカスタマイズ/上書きしやすくなります。
ビューの公開
アプリケーションのresources/views/vendor
ディレクトリに公開できるようにビューを利用可能にしたい場合は、サービスプロバイダーのpublishes
メソッドを使用できます。publishes
メソッドは、パッケージビューのパスとその希望する公開場所の配列を受け取ります:
/**
* Bootstrap the package services.
*/
public function boot(): void
{
$this->loadViewsFrom(__DIR__.'/../resources/views', 'courier');
$this->publishes([
__DIR__.'/../resources/views' => resource_path('views/vendor/courier'),
]);
}
これで、パッケージのユーザーがLaravelのvendor:publish
Artisanコマンドを実行すると、パッケージのビューが指定された公開場所にコピーされます。
ビューコンポーネント
Bladeコンポーネントを利用するパッケージを構築している場合や、非従来のディレクトリにコンポーネントを配置している場合は、Laravelがコンポーネントを見つけられるように、コンポーネントクラスとそのHTMLタグエイリアスを手動で登録する必要があります。通常、パッケージのサービスプロバイダーのboot
メソッドでコンポーネントを登録します:
use Illuminate\Support\Facades\Blade;
use VendorPackage\View\Components\AlertComponent;
/**
* Bootstrap your package's services.
*/
public function boot(): void
{
Blade::component('package-alert', AlertComponent::class);
}
コンポーネントが登録されると、そのタグエイリアスを使用してレンダリングできます:
<x-package-alert/>
パッケージコンポーネントの自動読み込み
また、componentNamespace
メソッドを使用して、慣例に従ってコンポーネントクラスを自動的に読み込むこともできます。たとえば、Nightshade
パッケージには、Calendar
およびColorPicker
コンポーネントがNightshade\Views\Components
名前空間内に存在する場合があります:
use Illuminate\Support\Facades\Blade;
/**
* Bootstrap your package's services.
*/
public function boot(): void
{
Blade::componentNamespace('Nightshade\\Views\\Components', 'nightshade');
}
これにより、package-name::
構文を使用してベンダー名前空間によるパッケージコンポーネントの使用が可能になります:
<x-nightshade::calendar />
<x-nightshade::color-picker />
Bladeは、コンポーネント名をパスカルケースにすることで、このコンポーネントにリンクされたクラスを自動的に検出します。サブディレクトリも「ドット」表記を使用してサポートされています。
匿名コンポーネント
パッケージに匿名コンポーネントが含まれている場合、それらはパッケージの「views」ディレクトリのcomponents
ディレクトリ内に配置する必要があります(loadViewsFrom
メソッドで指定)。その後、コンポーネント名をパッケージのビュー名前空間でプレフィックスすることでレンダリングできます:
<x-courier::alert />
「About」Artisanコマンド
Laravelの組み込みabout
Artisanコマンドは、アプリケーションの環境と設定の概要を提供します。パッケージは、このコマンドの出力に追加情報をプッシュすることができますAboutCommand
クラスを介して。通常、この情報はパッケージサービスプロバイダーのboot
メソッドから追加されます:
use Illuminate\Foundation\Console\AboutCommand;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
AboutCommand::add('My Package', fn () => ['Version' => '1.0.0']);
}
コマンド
パッケージのArtisanコマンドをLaravelに登録するには、commands
メソッドを使用します。このメソッドは、コマンドクラス名の配列を期待します。コマンドが登録されると、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,
]);
}
}
公開アセット
パッケージには、JavaScript、CSS、画像などのアセットが含まれている場合があります。これらのアセットをアプリケーションのpublic
ディレクトリに公開するには、サービスプロバイダーのpublishes
メソッドを使用します。この例では、関連するアセットのグループを簡単に公開できるようにpublic
アセットグループタグも追加します:
/**
* Bootstrap any package services.
*/
public function boot(): void
{
$this->publishes([
__DIR__.'/../public' => public_path('vendor/courier'),
], 'public');
}
これで、パッケージのユーザーがvendor:publish
コマンドを実行すると、アセットが指定された公開場所にコピーされます。ユーザーは通常、パッケージが更新されるたびにアセットを上書きする必要があるため、--force
フラグを使用できます:
php artisan vendor:publish --tag=public --force
ファイルグループの公開
パッケージアセットやリソースのグループを別々に公開したい場合があります。たとえば、ユーザーがパッケージのアセットを公開することなく、パッケージの設定ファイルを公開できるようにしたい場合があります。これを行うには、パッケージのサービスプロバイダーからpublishes
メソッドを呼び出すときに「タグ付け」します。たとえば、courier
パッケージのcourier-config
およびcourier-migrations
の2つの公開グループをboot
メソッドで定義するためにタグを使用しましょう:
/**
* 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');
}
これで、ユーザーはvendor:publish
コマンドを実行するときにタグを参照してこれらのグループを別々に公開できます:
php artisan vendor:publish --tag=courier-config