Package Development
Table of Contents
Introduction
パッケージは、 Laravel に機能を追加する primary な方法です。パッケージは、Carbon のように日付を扱う素晴らしい方法や、Spatie のLaravel Media Library のように、ファイルを Eloquent models に関連付けることを可能にするパッケージなど、さまざまなものがあり得ます。
さまざまな種類のパッケージがあります。一部のパッケージはスタンドアロン型で、任意の PHP フレームワークで動作します。 Carbon と Pest はスタンドアロンパッケージの例です。これらのパッケージは、あなたのcomposer.json
ファイルで必要とされていれば Laravel と共に使用することができます。
一方、他のパッケージは特に Laravel と一緒に使用することを目的としています。これらのパッケージには、特に Laravel application を強化するために意図された routes 、コントローラー、 views 、そして設定があるかもしれません。このガイドは主に、 Laravel 特有のそれらのパッケージの開発をカバーします。
Facades についての注意
Laravel application を書く際は、 contracts を使用するか facades を使用するかは、基本的にはテスト可能性のレベルが同等であるため、特に問題はありません。しかし、パッケージを作成する場合、パッケージは通常、Laravel の testing helpers 全体にアクセスできません。パッケージのテストをまるで通常の Laravel application 内にインストールされたかのように書きたい場合、Orchestral Testbench パッケージを使用することができます。
Package Discovery
Laravel application のbootstrap/providers.php
ファイルには、 Laravel によって読み込まれるべき service provider のリストが含まれています。しかし、 users が手動であなたの service providers をリストに追加する代わりに、パッケージのcomposer.json
ファイルのextra
セクションで provider を定義することで、それが自動的に Laravel によって読み込まれるようにできます。 service providers に加えて、登録したいfacadesもリストに追加できます。
"extra": {
"laravel": {
"providers": [
"Barryvdh\\Debugbar\\ServiceProvider"
],
"aliases": {
"Debugbar": "Barryvdh\\Debugbar\\Facade"
}
}
},
あなたのパッケージが検出用に設定されると、 Laravel は自動的にその register 、 service providers 、および facades をインストール時に登録し、パッケージの users にとって便利なインストール体験を作り出します。
パッケージディスカバリーのオプトアウト
パッケージの消費者であり、パッケージ検出を無効にしたい場合は、アプリケーションの composer.json
ファイルの extra
セクションにパッケージ名をリストすることができます:
"extra": {
"laravel": {
"dont-discover": [
"barryvdh/laravel-debugbar"
]
}
},
アプリケーションの dont-discover
ディレクティブの中で *
文字を使用して、すべてのパッケージのパッケージディスカバリを無効にすることができます:
"extra": {
"laravel": {
"dont-discover": [
"*"
]
}
},
Service Providers
Service providersはあなたのパッケージと Laravel との間の接続ポイントです。Service providers は、Laravel のservice container ーにものをバインドする責任を持ち、Laravel にパッケージの resources(views、設定、言語ファイルなど)をどこからロードするかを告げます。
service provider は、Illuminate\Support\ServiceProvider
class を拡張し、二つの method:register
とboot
、を含んでいます。基本のServiceProvider
class は、illuminate/support
Composer パッケージ内に位置しており、 それを自身のパッケージの依存性に追加するべきです。 service providers の構造と目的について詳しく知るには、そのドキュメンテーションを確認してください。
Resources
Configuration
通常、パッケージの設定ファイルをアプリケーションの config
ディレクトリに publish する必要があります。これにより、パッケージの users は default の設定 options を簡単に上書きすることができます。設定ファイルを公開するためには、 service provider の boot
method から publishes
method を呼び出します。
/**
* Bootstrap any package services.
*/
public function boot(): void
{
$this->publishes([
__DIR__.'/../config/courier.php' => config_path('courier.php'),
]);
}
さて、パッケージの users が Laravel の vendor:publish
command を実行すると、ファイルが指定されたパブリッシュ場所にコピーされます。設定が公開されると、その values は他の設定ファイルと同様にアクセスできます。
$value = config('courier.option');
WARNING
設定ファイルでクロージャを定義するべきではありません。 users が
config:cache
の Artisan command を実行するとき、正しくシリアライズできません。
Default パッケージ設定
あなたはまた、アプリケーションが公開しているコピーと自分のパッケージ設定ファイルを merge することができます。これにより、あなたの users が実際に上書きしたい options だけを公開コピーの設定ファイルで定義することができます。設定ファイルの values を merge するためには、あなたの service プロバイダの register
method で mergeConfigFrom
method を使用します。
mergeConfigFrom
method は、第一引数としてパッケージの設定ファイルへの path を、第二引数として application の設定ファイルの名前を受け付けます:
/**
* Register any application services.
*/
public function register(): void
{
$this->mergeConfigFrom(
__DIR__.'/../config/courier.php', 'courier'
);
}
WARNING
この method は、設定の array の最初のレベルのみをマージします。あなたの users が多次元の設定 array を部分的に定義すると、欠けている options はマージされません。
Routes
あなたのパッケージが routes を含んでいる場合、 loadRoutesFrom
method を使用してそれらをロードすることができます。この method は自動的にアプリケーションの routes がキャッシュされているかどうかを判断し、 routes がすでにキャッシュされていればあなたの routes ファイルはロードされません:
/**
* Bootstrap any package services.
*/
public function boot(): void
{
$this->loadRoutesFrom(__DIR__.'/../routes/web.php');
}
Migrations
あなたのパッケージがdatabasemigrationsを含んでいる場合、指定したディレクトリやファイルが migrations を含んでいることを Laravel に通知するために、publishesMigrations
method を使用することができます。Laravel が migrations を公開すると、それらのファイル名内の timestamp が自動的に現在の日付と時間を反映するように更新されます:
/**
* Bootstrap any package services.
*/
public function boot(): void
{
$this->publishesMigrations([
__DIR__.'/../database/migrations' => database_path('migrations'),
]);
}
言語ファイル
あなたのパッケージがlanguage filesを含んでいる場合、それらをロードする方法を Laravel に知らせるためにloadTranslationsFrom
method を使用することができます。例えば、あなたのパッケージがcourier
という名前である場合、以下をあなたの service プロバイダーのboot
method に追加すべきです:
/**
* Bootstrap any package services.
*/
public function boot(): void
{
$this->loadTranslationsFrom(__DIR__.'/../lang', 'courier');
}
パッケージ翻訳ラインは、package::file.line
syntax 規約を使用して参照されます。したがって、次のようにmessages
ファイルからcourier
パッケージのwelcome
ラインをロードすることができます:
echo trans('courier::messages.welcome');
あなたは loadJsonTranslationsFrom
method を使用してパッケージのための register JSON 翻訳ファイルを登録することができます。この method は、パッケージの JSON 翻訳ファイルが含まれているディレクトリへの path を受け入れます:
/**
* Bootstrap any package services.
*/
public function boot(): void
{
$this->loadJsonTranslationsFrom(__DIR__.'/../lang');
}
言語ファイルの公開
パッケージの言語ファイルを application のlang/vendor
ディレクトリに publish したい場合は、publishes
method を使用することができます。このpublishes
method は、パッケージの paths とその望ましい publish の場所を array として受け付けます。例えば、courier
パッケージの言語ファイルを publish するには、次のようにします:
/**
* Bootstrap any package services.
*/
public function boot(): void
{
$this->loadTranslationsFrom(__DIR__.'/../lang', 'courier');
$this->publishes([
__DIR__.'/../lang' => $this->app->langPath('vendor/courier'),
]);
}
さて、あなたのパッケージの users が Laravel のvendor:publish
Artisan command を実行すると、パッケージの言語ファイルが指定された publish 場所に公開されます。
Views
register するために、パッケージのviewsを Laravel に登録する必要があります。そのためには、 views が置かれている場所を Laravel に伝える必要があります。これは、loadViewsFrom
という service プロバイダの method を使用して行うことができます。 loadViewsFrom
method は二つの引数を受け取ります:テンプレートの view の path とあなたのパッケージの名前です。例えば、パッケージの名前が courier
の場合、以下のように service プロバイダの boot
method に追加します:
/**
* Bootstrap any package services.
*/
public function boot(): void
{
$this->loadViewsFrom(__DIR__.'/../resources/views', 'courier');
}
Package views はpackage::view
syntax 規約を用いて参照されます。ですので、一旦あなたの view path が service provider に登録されたら、courier
パッケージからdashboard
view をこのように読み込むことができます:
Route::get('/dashboard', function () {
return view('courier::dashboard');
});
パッケージ Views のオーバーライド
あなたがloadViewsFrom
の method を使用すると、 Laravel は実際にあなたの views のために 2 つの場所を登録します:アプリケーションのresources/views/vendor
ディレクトリとあなたが指定したディレクトリです。したがって、courier
パッケージを例にすると、 Laravel はまず、開発者がresources/views/vendor/courier
ディレクトリに配置した custom の view がないか確認します。次に、その view がカスタマイズされていない場合、 Laravel はあなたがloadViewsFrom
を呼び出すときに指定したパッケージの view ディレクトリを search します。これにより、パッケージの users はあなたのパッケージの views を簡単にカスタマイズ/上書きすることができます。
Views の公開
あなたが views をアプリケーションのresources/views/vendor
ディレクトリへ公開したいと考えているなら、 service プロバイダのpublishes
method を使用することができます。publishes
method は、パッケージの view パスとそれらが希望する publish 場所の array を受け入れます:
/**
* Bootstrap the package services.
*/
public function boot(): void
{
$this->loadViewsFrom(__DIR__.'/../resources/views', 'courier');
$this->publishes([
__DIR__.'/../resources/views' => resource_path('views/vendor/courier'),
]);
}
さて、あなたのパッケージの users が Laravel の vendor:publish
Artisan command を実行すると、あなたのパッケージの views が指定された公開場所にコピーされます。
View コンポーネント
Blade コンポーネントを利用するパッケージを作成していたり、コンポーネントを非標準的な directory に配置している場合は、 Laravel が component をどこで見つけるかを知るために、 component class とその HTML タグエイリアスを手動で register しなければなりません。通常、パッケージの service provider のboot
method でコンポーネントを register `すべきです:
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);
}
あなたの component が登録されたら、そのタグエイリアスを使用してレンダリングすることができます:
<x-package-alert/>
Autoloading Package Components
あるいは、componentNamespace
method を使って、 component classes を規則に従って自動的に読み込むこともできます。例えば、Nightshade
パッケージには、Nightshade\Views\Components
名前空間内に存在するCalendar
とColorPicker
コンポーネントがあるかもしれません:
use Illuminate\Support\Facades\Blade;
/**
* Bootstrap your package's services.
*/
public function boot(): void
{
Blade::componentNamespace('Nightshade\\Views\\Components', 'nightshade');
}
これにより、package-name::
の syntax を使用して、パッケージのコンポーネントをその vendor 名前空間で使用することができます。
<x-nightshade::calendar />
<x-nightshade::color-picker />
Blade は、 component の名前をパスカルケースにすることで、この component にリンクされた class を自動的に検出します。また、"dot" 表記を使用してサブディレクトリもサポートしています
匿名コンポーネント
もしパッケージに無名 component が含まれている場合、それらはパッケージの"views"ディレクトリー(loadViewsFrom
methodにて指定されているように)のcomponents
ディレクトリー内に配置しなければなりません。その後、パッケージの view ネームスペースで component の名前をプレフィックスとして、それらを render することができます:
<x-courier::alert />
"About" Artisan Command について
Laravel の組み込みabout
の Artisan command は、application の環境と設定の概要を提供します。パッケージは、AboutCommand
の class を介して、この command の出力に追加情報をプッシュすることができます。通常、この情報はパッケージの serviceprovider のboot
の method から追加することができます:
use Illuminate\Foundation\Console\AboutCommand;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
AboutCommand::add('My Package', fn () => ['Version' => '1.0.0']);
}
Commands
あなたのパッケージの Artisan commands を Laravel に登録するために、commands
method を使用することができます。この method は、command class の名前の array を期待します。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,
]);
}
}
Public Assets
あなたのパッケージには、 JavaScript 、 CSS 、画像などのアセットが含まれている場合があります。これらのアセットをアプリケーションの public
ディレクトリに publish するには、 service プロバイダの publishes
method を使用します。この例では、関連するアセットのグループを簡単に publish するために使用できる public
アセットグループタグを追加します:
/**
* Bootstrap any package services.
*/
public function boot(): void
{
$this->publishes([
__DIR__.'/../public' => public_path('vendor/courier'),
], 'public');
}
さて、あなたのパッケージの users がvendor:publish
command を実行すると、あなたのアセットは指定された publish の場所にコピーされます。 users は通常、パッケージが更新されるたびにアセットを上書きする必要がありますので、--force
フラグを使用することができます。
php artisan vendor:publish --tag=public --force
Publishing File Groups
あなたは、パッケージの資産や resources を別々に「 publish 」したいかもしれません。例えば、あなたのパッケージの設定ファイルを強制的にパッケージの資産を「 publish 」せずに、 users に「 publish 」を許可したくなるかもしれません。これはpublishes
method をパッケージの「 service provider 」から呼び出す際に、それらに「tagging」することで実現できます。例えば、パッケージの「 service provider 」の boot
method で、courier
パッケージの「 publish 」の2つのグループ(courier-config
と courier-migrations
)を定義するために、「 tags 」を使用しましょう:
/**
* 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');
}
現在、あなたの users は、vendor:publish
command を実行する際に、そのタグを参照してこれらのグループを別々に publish することができます。
php artisan vendor:publish --tag=courier-config