はじめに

パッケージは、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によって自動的に読み込まれるようにできます。サービスプロバイダーに加えて、登録したいファサードをリストすることもできます:

  1. "extra": {
  2. "laravel": {
  3. "providers": [
  4. "Barryvdh\\Debugbar\\ServiceProvider"
  5. ],
  6. "aliases": {
  7. "Debugbar": "Barryvdh\\Debugbar\\Facade"
  8. }
  9. }
  10. },

パッケージが発見のために構成されると、Laravelはインストール時に自動的にそのサービスプロバイダーとファサードを登録し、パッケージのユーザーにとって便利なインストール体験を提供します。

パッケージの発見を無効にする

パッケージの消費者であり、パッケージの発見を無効にしたい場合は、アプリケーションのcomposer.jsonファイルのextraセクションにパッケージ名をリストすることができます:

  1. "extra": {
  2. "laravel": {
  3. "dont-discover": [
  4. "barryvdh/laravel-debugbar"
  5. ]
  6. }
  7. },

アプリケーションのdont-discoverディレクティブ内で*文字を使用して、すべてのパッケージの発見を無効にすることもできます:

  1. "extra": {
  2. "laravel": {
  3. "dont-discover": [
  4. "*"
  5. ]
  6. }
  7. },

サービスプロバイダー

サービスプロバイダーは、パッケージとLaravelの接続ポイントです。サービスプロバイダーは、Laravelのサービスコンテナに物事をバインドし、ビュー、設定、言語ファイルなどのパッケージリソースをどこから読み込むかをLaravelに通知する責任があります。

サービスプロバイダーはIlluminate\Support\ServiceProviderクラスを拡張し、registerbootの2つのメソッドを含みます。基本のServiceProviderクラスはilluminate/support Composerパッケージにあり、これを自分のパッケージの依存関係に追加する必要があります。サービスプロバイダーの構造と目的について詳しく知りたい場合は、そのドキュメントを確認してください。

リソース

設定

通常、パッケージの設定ファイルをアプリケーションのconfigディレクトリに公開する必要があります。これにより、パッケージのユーザーはデフォルトの設定オプションを簡単に上書きできます。設定ファイルを公開できるようにするには、サービスプロバイダーのbootメソッドからpublishesメソッドを呼び出します:

  1. /**
  2. * Bootstrap any package services.
  3. */
  4. public function boot(): void
  5. {
  6. $this->publishes([
  7. __DIR__.'/../config/courier.php' => config_path('courier.php'),
  8. ]);
  9. }

これで、パッケージのユーザーがLaravelのvendor:publishコマンドを実行すると、指定された公開場所にファイルがコピーされます。設定が公開された後、その値は他の設定ファイルと同様にアクセスできます:

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

設定ファイルにクロージャを定義してはいけません。ユーザーがconfig:cache Artisanコマンドを実行するときに正しくシリアライズできません。

デフォルトのパッケージ設定

自分のパッケージ設定ファイルをアプリケーションの公開コピーとマージすることもできます。これにより、ユーザーは公開された設定ファイルのコピーで実際に上書きしたいオプションのみを定義できます。設定ファイルの値をマージするには、サービスプロバイダーのregisterメソッド内でmergeConfigFromメソッドを使用します。

  1. ``````php
  2. /**
  3. * Register any application services.
  4. */
  5. public function register(): void
  6. {
  7. $this->mergeConfigFrom(
  8. __DIR__.'/../config/courier.php', 'courier'
  9. );
  10. }
  11. `

このメソッドは、設定配列の最初のレベルのみをマージします。ユーザーが多次元設定配列を部分的に定義した場合、欠落しているオプションはマージされません。

ルート

パッケージにルートが含まれている場合、loadRoutesFromメソッドを使用してそれらを読み込むことができます。このメソッドは、アプリケーションのルートがキャッシュされているかどうかを自動的に判断し、ルートがすでにキャッシュされている場合はルートファイルを読み込みません:

  1. /**
  2. * Bootstrap any package services.
  3. */
  4. public function boot(): void
  5. {
  6. $this->loadRoutesFrom(__DIR__.'/../routes/web.php');
  7. }

マイグレーション

パッケージにデータベースマイグレーションが含まれている場合、publishesMigrationsメソッドを使用してLaravelに指定されたディレクトリまたはファイルがマイグレーションを含むことを通知できます。Laravelがマイグレーションを公開すると、ファイル名内のタイムスタンプが現在の日付と時刻を反映するように自動的に更新されます:

  1. /**
  2. * Bootstrap any package services.
  3. */
  4. public function boot(): void
  5. {
  6. $this->publishesMigrations([
  7. __DIR__.'/../database/migrations' => database_path('migrations'),
  8. ]);
  9. }

言語ファイル

パッケージに言語ファイルが含まれている場合、loadTranslationsFromメソッドを使用してLaravelにそれらを読み込む方法を通知できます。たとえば、パッケージの名前がcourierの場合、サービスプロバイダーのbootメソッドに次のように追加する必要があります:

  1. /**
  2. * Bootstrap any package services.
  3. */
  4. public function boot(): void
  5. {
  6. $this->loadTranslationsFrom(__DIR__.'/../lang', 'courier');
  7. }

パッケージの翻訳行は、package::file.line構文規約を使用して参照されます。したがって、messagesファイルからwelcome行を次のように読み込むことができます:

  1. echo trans('courier::messages.welcome');
  1. ``````php
  2. /**
  3. * Bootstrap any package services.
  4. */
  5. public function boot(): void
  6. {
  7. $this->loadJsonTranslationsFrom(__DIR__.'/../lang');
  8. }
  9. `

言語ファイルの公開

パッケージの言語ファイルをアプリケーションのlang/vendorディレクトリに公開したい場合は、サービスプロバイダーのpublishesメソッドを使用できます。publishesメソッドは、パッケージパスとその希望する公開場所の配列を受け取ります。たとえば、courierパッケージの言語ファイルを公開するには、次のようにします:

  1. /**
  2. * Bootstrap any package services.
  3. */
  4. public function boot(): void
  5. {
  6. $this->loadTranslationsFrom(__DIR__.'/../lang', 'courier');
  7. $this->publishes([
  8. __DIR__.'/../lang' => $this->app->langPath('vendor/courier'),
  9. ]);
  10. }

これで、パッケージのユーザーがLaravelのvendor:publish Artisanコマンドを実行すると、パッケージの言語ファイルが指定された公開場所に公開されます。

ビュー

パッケージのビューをLaravelに登録するには、Laravelにビューの場所を知らせる必要があります。サービスプロバイダーのloadViewsFromメソッドを使用してこれを行うことができます。loadViewsFromメソッドは、ビューのテンプレートへのパスとパッケージの名前の2つの引数を受け取ります。たとえば、パッケージの名前がcourierの場合、サービスプロバイダーのbootメソッドに次のように追加します:

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

パッケージのビューは、package::view構文規約を使用して参照されます。したがって、サービスプロバイダーにビューのパスが登録されると、次のようにdashboardビューをcourierパッケージから読み込むことができます:

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

パッケージビューの上書き

loadViewsFromメソッドを使用すると、Laravelは実際にビューのために2つの場所を登録します: アプリケーションのresources/views/vendorディレクトリと指定したディレクトリです。したがって、courierパッケージを例にすると、Laravelは最初に開発者によってresources/views/vendor/courierディレクトリにカスタムバージョンのビューが配置されているかどうかを確認します。次に、ビューがカスタマイズされていない場合、LaravelはloadViewsFromへの呼び出しで指定したパッケージビューのディレクトリを検索します。これにより、パッケージユーザーはパッケージのビューをカスタマイズ/上書きしやすくなります。

ビューの公開

アプリケーションのresources/views/vendorディレクトリに公開できるようにビューを利用可能にしたい場合は、サービスプロバイダーのpublishesメソッドを使用できます。publishesメソッドは、パッケージビューのパスとその希望する公開場所の配列を受け取ります:

  1. /**
  2. * Bootstrap the package services.
  3. */
  4. public function boot(): void
  5. {
  6. $this->loadViewsFrom(__DIR__.'/../resources/views', 'courier');
  7. $this->publishes([
  8. __DIR__.'/../resources/views' => resource_path('views/vendor/courier'),
  9. ]);
  10. }

これで、パッケージのユーザーがLaravelのvendor:publish Artisanコマンドを実行すると、パッケージのビューが指定された公開場所にコピーされます。

ビューコンポーネント

Bladeコンポーネントを利用するパッケージを構築している場合や、非従来のディレクトリにコンポーネントを配置している場合は、Laravelがコンポーネントを見つけられるように、コンポーネントクラスとそのHTMLタグエイリアスを手動で登録する必要があります。通常、パッケージのサービスプロバイダーのbootメソッドでコンポーネントを登録します:

  1. use Illuminate\Support\Facades\Blade;
  2. use VendorPackage\View\Components\AlertComponent;
  3. /**
  4. * Bootstrap your package's services.
  5. */
  6. public function boot(): void
  7. {
  8. Blade::component('package-alert', AlertComponent::class);
  9. }

コンポーネントが登録されると、そのタグエイリアスを使用してレンダリングできます:

  1. <x-package-alert/>

パッケージコンポーネントの自動読み込み

また、componentNamespaceメソッドを使用して、慣例に従ってコンポーネントクラスを自動的に読み込むこともできます。たとえば、Nightshadeパッケージには、CalendarおよびColorPickerコンポーネントがNightshade\Views\Components名前空間内に存在する場合があります:

  1. use Illuminate\Support\Facades\Blade;
  2. /**
  3. * Bootstrap your package's services.
  4. */
  5. public function boot(): void
  6. {
  7. Blade::componentNamespace('Nightshade\\Views\\Components', 'nightshade');
  8. }

これにより、package-name::構文を使用してベンダー名前空間によるパッケージコンポーネントの使用が可能になります:

  1. <x-nightshade::calendar />
  2. <x-nightshade::color-picker />

Bladeは、コンポーネント名をパスカルケースにすることで、このコンポーネントにリンクされたクラスを自動的に検出します。サブディレクトリも「ドット」表記を使用してサポートされています。

匿名コンポーネント

パッケージに匿名コンポーネントが含まれている場合、それらはパッケージの「views」ディレクトリのcomponentsディレクトリ内に配置する必要があります(loadViewsFromメソッドで指定)。その後、コンポーネント名をパッケージのビュー名前空間でプレフィックスすることでレンダリングできます:

  1. <x-courier::alert />

「About」Artisanコマンド

Laravelの組み込みabout Artisanコマンドは、アプリケーションの環境と設定の概要を提供します。パッケージは、このコマンドの出力に追加情報をプッシュすることができますAboutCommandクラスを介して。通常、この情報はパッケージサービスプロバイダーのbootメソッドから追加されます:

  1. use Illuminate\Foundation\Console\AboutCommand;
  2. /**
  3. * Bootstrap any application services.
  4. */
  5. public function boot(): void
  6. {
  7. AboutCommand::add('My Package', fn () => ['Version' => '1.0.0']);
  8. }

コマンド

パッケージのArtisanコマンドをLaravelに登録するには、commandsメソッドを使用します。このメソッドは、コマンドクラス名の配列を期待します。コマンドが登録されると、Artisan CLIを使用して実行できます:

  1. use Courier\Console\Commands\InstallCommand;
  2. use Courier\Console\Commands\NetworkCommand;
  3. /**
  4. * Bootstrap any package services.
  5. */
  6. public function boot(): void
  7. {
  8. if ($this->app->runningInConsole()) {
  9. $this->commands([
  10. InstallCommand::class,
  11. NetworkCommand::class,
  12. ]);
  13. }
  14. }

公開アセット

パッケージには、JavaScript、CSS、画像などのアセットが含まれている場合があります。これらのアセットをアプリケーションのpublicディレクトリに公開するには、サービスプロバイダーのpublishesメソッドを使用します。この例では、関連するアセットのグループを簡単に公開できるようにpublicアセットグループタグも追加します:

  1. /**
  2. * Bootstrap any package services.
  3. */
  4. public function boot(): void
  5. {
  6. $this->publishes([
  7. __DIR__.'/../public' => public_path('vendor/courier'),
  8. ], 'public');
  9. }

これで、パッケージのユーザーがvendor:publishコマンドを実行すると、アセットが指定された公開場所にコピーされます。ユーザーは通常、パッケージが更新されるたびにアセットを上書きする必要があるため、--forceフラグを使用できます:

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

ファイルグループの公開

パッケージアセットやリソースのグループを別々に公開したい場合があります。たとえば、ユーザーがパッケージのアセットを公開することなく、パッケージの設定ファイルを公開できるようにしたい場合があります。これを行うには、パッケージのサービスプロバイダーからpublishesメソッドを呼び出すときに「タグ付け」します。たとえば、courierパッケージのcourier-configおよびcourier-migrationsの2つの公開グループをbootメソッドで定義するためにタグを使用しましょう:

  1. /**
  2. * Bootstrap any package services.
  3. */
  4. public function boot(): void
  5. {
  6. $this->publishes([
  7. __DIR__.'/../config/package.php' => config_path('package.php')
  8. ], 'courier-config');
  9. $this->publishesMigrations([
  10. __DIR__.'/../database/migrations/' => database_path('migrations')
  11. ], 'courier-migrations');
  12. }

これで、ユーザーはvendor:publishコマンドを実行するときにタグを参照してこれらのグループを別々に公開できます:

  1. php artisan vendor:publish --tag=courier-config