本文へ移動
Laravel Tips

パッケージを作る

Laravel 向けのパッケージ(追加の部品)を作る方法を、自動の登録・サービスプロバイダ・設定・ルート・ビュー・コマンド・公開するファイルのまとめ方まで説明します。

パッケージは、Laravel に機能を足す、いちばん基本の方法です。日付を扱う Carbon や、ファイルを Eloquent のモデルに結びつける Spatie の Laravel Media Library のように、さまざまなものがあります。

パッケージには、いろいろな種類があります。どの PHP のフレームワーク(アプリ作りの土台になる道具一式)でも使える、独立したパッケージ(Carbon や Pest など)もあります。これらは composer.json(Composer というパッケージ管理の道具の設定ファイル)に書けば、Laravel でも使えます。一方、Laravel 専用のパッケージもあります。Laravel のアプリを便利にする、ルート・コントローラー・ビュー・設定を持つものです。このページでは、主に、この Laravel 専用のパッケージの作り方を説明します。

パッケージを作りはじめる#

新しい Laravel のパッケージを作りはじめる、いちばん簡単な方法は、公式の Laravel package skeleton(雛形)を使うことです。パッケージ作りに必要なものが、そろっています。たとえば、サービスプロバイダ、Pest によるテスト、Larastan による静的解析(動かさずにコードを調べること)、Pint によるコードの整形、パッケージを実際のアプリのように動かして試す workbench アプリです。Laravel インストーラの package コマンドで作れます(インストールを見てください)。

bash
laravel package my-package

対話式の設定スクリプトが、雛形を、自分のパッケージ向けに整えます。名前空間(クラスの住所のようなもの)・サービスプロバイダ・必要な機能(設定ファイル・ルート・ビュー・翻訳・マイグレーション・アセット・コマンド・ファサード)だけを選びます。

ファサードについて#

Laravel のアプリを作るときは、コントラクト(決まった形の約束事)を使っても、ファサード(Route::get() のように、クラス名と :: で機能を呼べる窓口)を使っても、テストのしやすさは、ほぼ同じです。ただ、パッケージを作るときは、Laravel のテスト用の道具のすべてを、ふつうは使えません。ふつうの Laravel アプリに入れたときと同じように、パッケージのテストを書きたいなら、Orchestral Testbench というパッケージが使えます。

パッケージの自動発見#

Laravel のアプリの bootstrap/providers.php には、Laravel が読み込む、サービスプロバイダの一覧があります。パッケージを使う人に、ここへサービスプロバイダを手で足してもらわなくても済みます。パッケージの composer.json の extra に書いておけば、Laravel が自動で読み込みます。サービスプロバイダのほかに、登録したいファサードも書けます。

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

自動発見の設定をしておくと、パッケージをインストールしたときに、Laravel が、サービスプロバイダとファサードを、自動で登録します。パッケージを使う人にとって、楽な導入になります。

自動発見を止める#

パッケージを使う側で、あるパッケージの自動発見を止めたいときは、アプリの composer.json の extra に、パッケージの名前を書きます。

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

アプリの dont-discover に * を書くと、すべてのパッケージの自動発見を止められます。

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

サービスプロバイダ#

サービスプロバイダ(アプリの起動のときに、道具箱へ道具を登録する場所)は、パッケージと Laravel をつなぐ接点です。サービスプロバイダの仕事は、Laravel のサービスコンテナ(クラスを作って渡してくれる道具箱のようなしくみ)に道具を結びつけることと、ビュー・設定・言語ファイルのような、パッケージの部品を、どこから読み込むかを Laravel に知らせることです。

サービスプロバイダは、Illuminate\Support\ServiceProvider を継承して(もとにして)作り、register と boot の2つのメソッドを持ちます。土台の ServiceProvider は、illuminate/support という Composer のパッケージにあります。自分のパッケージの依存(動くのに必要なほかのパッケージ)に足してください。サービスプロバイダの作りと目的は、サービスプロバイダのページを見てください。

パッケージの部品#

設定#

ふつう、パッケージの設定ファイルを、アプリの config フォルダへ公開(コピー)できるようにします。パッケージを使う人が、標準の設定を、簡単に上書きできるようになります。サービスプロバイダの boot の中で、publishes を呼びます。

php
/**
 * パッケージのサービスを起動する
 */
public function boot(): void
{
    $this->publishes([
        __DIR__.'/../config/courier.php' => config_path('courier.php'),
    ]);
}

これで、パッケージを使う人が vendor:publish コマンドを実行すると、そのファイルが、決めた場所にコピーされます。公開したあとは、ほかの設定ファイルと同じように、値を取り出せます。

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

注意

設定ファイルの中に、クロージャ(名前のない関数)を書かないでください。使う人が config:cache という Artisan コマンドを実行したときに、正しく保存できなくなります。

パッケージの標準の設定#

パッケージの設定ファイルを、アプリに公開された設定ファイルと、混ぜ合わせることもできます。使う人は、上書きしたいオプションだけを、公開した設定ファイルに書けばよくなります。混ぜ合わせるには、サービスプロバイダの register の中で、mergeConfigFrom を呼びます。

mergeConfigFrom の第1引数は、パッケージの設定ファイルの場所、第2引数は、アプリ側の設定ファイルの名前です。

php
/**
 * パッケージのサービスを登録する
 */
public function register(): void
{
    $this->mergeConfigFrom(
        __DIR__.'/../config/courier.php', 'courier'
    );
}

注意

このメソッドが混ぜ合わせるのは、設定の配列の、いちばん上の階層だけです。使う人が、入れ子の配列を一部だけ書くと、足りないオプションは混ぜ合わされません。

ルート#

パッケージにルート(URL と処理を結びつけたもの)があるなら、loadRoutesFrom で読み込めます。アプリのルートが、キャッシュ(保存して使い回すこと)されているかを自動で調べ、すでにキャッシュされていれば、パッケージのルートのファイルは読み込みません。

php
/**
 * パッケージのサービスを起動する
 */
public function boot(): void
{
    $this->loadRoutesFrom(__DIR__.'/../routes/web.php');
}

マイグレーション#

パッケージに、マイグレーション(データベースの表を作ったり変えたりする手順書)があるなら、publishesMigrations で、そのフォルダかファイルがマイグレーションだと、Laravel に知らせます。Laravel がマイグレーションを公開するとき、ファイル名の日時を、いまの日時に、自動で書き換えます。

php
/**
 * パッケージのサービスを起動する
 */
public function boot(): void
{
    $this->publishesMigrations([
        __DIR__.'/../database/migrations' => database_path('migrations'),
    ]);
}

言語ファイル#

パッケージに、言語ファイル(文章を言語ごとに置いたファイル)があるなら、loadTranslationsFrom で、読み込み方を Laravel に知らせます。たとえば、パッケージの名前が courier なら、サービスプロバイダの boot に、次のように書きます。

php
/**
 * パッケージのサービスを起動する
 */
public function boot(): void
{
    $this->loadTranslationsFrom(__DIR__.'/../lang', 'courier');
}

パッケージの翻訳の文は、パッケージ名::ファイル名.キー の形で呼び出します。たとえば、courier パッケージの、messages ファイルの welcome の文は、次のように読み込みます。

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

JSON の翻訳ファイルは、loadJsonTranslationsFrom で登録できます。パッケージの JSON の翻訳ファイルがあるフォルダを渡します。

php
/**
 * パッケージのサービスを起動する
 */
public function boot(): void
{
    $this->loadJsonTranslationsFrom(__DIR__.'/../lang');
}

言語ファイルを公開する#

パッケージの言語ファイルを、アプリの lang/vendor フォルダへ公開したいなら、サービスプロバイダの publishes を使います。publishes は、パッケージ内の場所と、公開先の場所の組の配列を受け取ります。たとえば、courier の言語ファイルを公開するときは、次のように書きます。

php
/**
 * パッケージのサービスを起動する
 */
public function boot(): void
{
    $this->loadTranslationsFrom(__DIR__.'/../lang', 'courier');

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

これで、パッケージを使う人が vendor:publish という Artisan コマンドを実行すると、パッケージの言語ファイルが、決めた場所へ公開されます。

ビュー#

パッケージのビュー(画面の見た目を書いたファイル)を Laravel に登録するには、ビューの場所を Laravel に知らせる必要があります。サービスプロバイダの loadViewsFrom を使います。引数は2つで、ビューのテンプレートの場所と、パッケージの名前です。たとえば、パッケージの名前が courier なら、サービスプロバイダの boot に、次のように書きます。

php
/**
 * パッケージのサービスを起動する
 */
public function boot(): void
{
    $this->loadViewsFrom(__DIR__.'/../resources/views', 'courier');
}

パッケージのビューは、パッケージ名::ビュー名 の形で呼び出します。ビューの場所を、サービスプロバイダに登録したら、たとえば、courier パッケージの dashboard ビューを、次のように読み込めます。

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

パッケージのビューを上書きする#

loadViewsFrom を使うと、Laravel は、ビューの場所を2か所に登録します。アプリの resources/views/vendor フォルダと、指定したフォルダです。courier パッケージなら、まず、開発者が、resources/views/vendor/courier に、そのビューの自分用の版を置いているかを調べます。置いていなければ、loadViewsFrom で指定した、パッケージのビューのフォルダから探します。このおかげで、パッケージを使う人は、パッケージのビューを、簡単に変えたり、上書きしたりできます。

ビューを公開する#

ビューを、アプリの resources/views/vendor フォルダへ公開できるようにするには、サービスプロバイダの publishes を使います。publishes は、パッケージのビューの場所と、公開先の場所の組の配列を受け取ります。

php
/**
 * パッケージのサービスを起動する
 */
public function boot(): void
{
    $this->loadViewsFrom(__DIR__.'/../resources/views', 'courier');

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

これで、パッケージを使う人が vendor:publish を実行すると、パッケージのビューが、決めた場所へコピーされます。

ビューコンポーネント#

パッケージが Blade のコンポーネント(何度も使う画面の部品。Blade コンポーネントを見てください)を使うとき、または決まりとちがう場所に置くときは、手で登録する必要があります。コンポーネントのクラスと、HTML のタグの別名を登録して、Laravel に場所を教えます。ふつう、パッケージのサービスプロバイダの boot の中で登録します。

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

/**
 * パッケージのサービスを起動する
 */
public function boot(): void
{
    Blade::component('package-alert', AlertComponent::class);
}

登録したら、タグの別名で、コンポーネントを表示できます。

blade
<x-package-alert/>

コンポーネントを決まりで自動で読み込む#

componentNamespace を使うと、名前の決まりで、コンポーネントのクラスを、自動で読み込めます。たとえば、Nightshade パッケージに、Nightshade\Views\Components という名前空間の中に、Calendar と ColorPicker のコンポーネントがあるとします。

php
use Illuminate\Support\Facades\Blade;

/**
 * パッケージのサービスを起動する
 */
public function boot(): void
{
    Blade::componentNamespace('Nightshade\\Views\\Components', 'nightshade');
}

これで、パッケージ名:: の形で、パッケージのコンポーネントを使えます。

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

Blade は、コンポーネントの名前を、パスカルケース(単語の頭を大文字にしてつなぐ書き方)にして、結びつくクラスを、自動で見つけます。サブフォルダも、ドット(.)で書けます。

匿名コンポーネント#

パッケージに、匿名コンポーネント(クラスを持たない、ビューだけのコンポーネント)があるなら、パッケージの「views」フォルダ(loadViewsFrom で決めた場所)の中の、components フォルダに置く必要があります。表示するときは、コンポーネントの名前の前に、パッケージのビューの名前(名前空間)を付けます。

blade
<x-courier::alert />

about の Artisan コマンド#

Laravel に入っている about という Artisan コマンドは、アプリの環境と設定の概要を出します。パッケージは、AboutCommand を使って、このコマンドの出力に、情報を足せます。ふつう、パッケージのサービスプロバイダの boot の中で足します。

php
use Illuminate\Foundation\Console\AboutCommand;

/**
 * パッケージのサービスを起動する
 */
public function boot(): void
{
    AboutCommand::add('My Package', fn () => ['Version' => '1.0.0']);
}

コマンド#

パッケージの Artisan コマンド(php artisan で動かす Laravel のコマンド)を Laravel に登録するには、commands を使います。コマンドのクラスの名前の配列を渡します。登録したあとは、Artisan の CLI で動かせます。

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

/**
 * パッケージのサービスを起動する
 */
public function boot(): void
{
    if ($this->app->runningInConsole()) {
        $this->commands([
            InstallCommand::class,
            NetworkCommand::class,
        ]);
    }
}

最適化のコマンド#

Laravel の最適化のコマンド(本番へ公開するを見てください)は、アプリの設定・イベント・ルート・ビューを、キャッシュします。optimizes で、optimize と optimize:clear を実行したときに、あわせて動かしたい、パッケージ自身の Artisan コマンドを登録できます。

php
/**
 * パッケージのサービスを起動する
 */
public function boot(): void
{
    if ($this->app->runningInConsole()) {
        $this->optimizes(
            optimize: 'package:optimize',
            clear: 'package:clear-optimizations',
        );
    }
}

再読み込みのコマンド#

Laravel の再読み込みのコマンド(本番へ公開するを見てください)は、動いているサービスをすべて止めて、システムのプロセス監視のしくみが、自動で再び起動できるようにします。reloads で、reload を実行したときに動かしたい、パッケージ自身の Artisan コマンドを登録できます。

php
/**
 * パッケージのサービスを起動する
 */
public function boot(): void
{
    if ($this->app->runningInConsole()) {
        $this->reloads('package:reload');
    }
}

公開するアセット#

パッケージには、JavaScript・CSS・画像などの、アセット(付属のファイル)があることもあります。これらを、アプリの public フォルダへ公開するには、サービスプロバイダの publishes を使います。次の例では、関連するアセットをまとめて公開しやすいように、public というグループのタグも付けています。

php
/**
 * パッケージのサービスを起動する
 */
public function boot(): void
{
    $this->publishes([
        __DIR__.'/../public' => public_path('vendor/courier'),
    ], 'public');
}

これで、パッケージを使う人が vendor:publish を実行すると、アセットが、決めた場所へコピーされます。パッケージを更新するたびに、アセットを上書きすることが多いので、そのときは --force を付けて実行できます。

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

公開するファイルをグループに分ける#

パッケージのアセットや部品を、グループごとに分けて公開したいことがあります。たとえば、設定ファイルだけを公開して、アセットは公開させたくないときです。サービスプロバイダの publishes を呼ぶときに、「タグ」を付けると、グループに分けられます。たとえば、courier パッケージに、2つの公開のグループ(courier-config と courier-migrations)を作る例です。

php
/**
 * パッケージのサービスを起動する
 */
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 を実行するときに、タグを指定して、グループを別々に公開できます。

bash
php artisan vendor:publish --tag=courier-config

--provider を付けると、パッケージのサービスプロバイダが公開できるファイルを、すべて公開できます。

bash
php artisan vendor:publish --provider="Your\Package\ServiceProvider"

サービスプロバイダのメソッドの一覧#

このページで使った、サービスプロバイダのメソッドを、まとめます。

メソッド 説明
publishes 設定・言語ファイル・ビュー・アセットなどを、アプリへ公開できるようにする
publishesMigrations マイグレーションを、アプリへ公開できるようにする(ファイル名の日時を、公開するときの日時に書き換える)
mergeConfigFrom パッケージの設定を、アプリの設定と混ぜ合わせる(register で呼ぶ。混ぜるのは、いちばん上の階層だけ)
loadRoutesFrom パッケージのルートを読み込む(ルートがキャッシュ済みなら読み込まない)
loadTranslationsFrom パッケージの言語ファイルの場所を、Laravel に知らせる
loadJsonTranslationsFrom パッケージの JSON の翻訳ファイルの場所を、Laravel に知らせる
loadViewsFrom パッケージのビューの場所を、Laravel に知らせる
commands パッケージの Artisan コマンドを登録する
optimizes optimize と optimize:clear のときに動かすコマンドを登録する
reloads reload のときに動かすコマンドを登録する

関連するページ#

公式ドキュメント(英語)

2026年10月5日時点の内容をもとに、日本語でまとめています。

ページの一覧