環境
- Laravel 5.1LTS
- Composer 1.4
概要
Laravelを使用していて、require-devオプションに開発用パッケージを導入する事があるかと思います。
私の環境ですとrequire-dev
には以下のパッケージを記載しています
"require-dev": {
"barryvdh/laravel-ide-helper": "@stable",
"barryvdh/laravel-debugbar": "^2.3",
"fzaninotto/faker": "~1.4",
"mockery/mockery": "0.9.*",
"phpunit/phpunit": "^5.3",
"phpspec/phpspec": "~2.1"
},
開発用パッケージは本番環境では不要ですので、--no-dev
オプションを付けcomposerコマンドを実行します
$ composer install --no-dev
そうするとrequire-devオプションに記載されているライブラリ自体はvendorへインストールされませんが、
ServiceProvider登録が必要なライブラリをconfig/app.php
に記載している場合、Laravelの起動時にエラーとなります。
'providers' => [
Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class,
Barryvdh\Debugbar\ServiceProvider::class,
],
'aliases' => [
'Debugbar' => 'Barryvdh\Debugbar\Facade',
],
IdeHelperServiceProviderに関してはcomposer.json
のpost-xxxx-cmdオプションで、php artisan ide-helper
を実行するよう設計されているため、composer install --no-dev
を実行した際にクラスが見つからずこちらもエラーになります。
"scripts": {
"post-install-cmd": [
"Illuminate\\Foundation\\ComposerScripts::postInstall",
"php artisan ide-helper:generate",
"php artisan ide-helper:meta",
"php artisan optimize"
]
このような問題を解決するため以下のように対応します。
- config/app.phpに記載していたproviders, aliasesを別ファイルに分けます。
※ ファイル名やディレクトリは好きに変更してください
'providers' => [
'Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider',
'Barryvdh\Debugbar\ServiceProvider',
],
'aliases' => [
'Debugbar' => 'Barryvdh\Debugbar\Facade',
],
- .envに環境変数を追加します
REQUIRE_DEV=true
- AppServiceProviderに以下を追記します
public function register()
{
if (!env('REQUIRE_DEV', false)) {
return;
}
$providers = config('dev.app.providers', []);
foreach ($providers as $provider) {
if (class_exists($provider)) {
$this->app->register($provider);
}
}
$aliases = config('dev.app.aliases', []);
foreach ($aliases as $alias => $facade) {
if (class_exists($facade)) {
$this->app->alias($alias, $facade );
}
}
}
これでrequire-devに定義されてるパッケージは、REQUIRE_DEV=true
の時のみロードされるようになります。
しかし、composer.jsonの"post-install-cmd"に記載したphp artisan ide-helper:generate
が実行されてしまうため、こちらも対応を行う必要があります。
artisanコマンドとして実行できるクラスを作成します。
<?php namespace App\Console\Commands;
use Illuminate\Console\Command;
class ComposerPostScripts extends Command
{
protected $name = 'app:update';
protected $description = 'Command description.';
public function handle()
{
if (env('REQUIRE_DEV', false)) {
$this->call('ide-helper:generate');
$this->call('ide-helper:meta');
}
}
}
作成したCommandクラスをcomposer.json
に登録します。
"post-install-cmd": [
"Illuminate\\Foundation\\ComposerScripts::postInstall",
"php artisan app:update",
"php artisan optimize"
],
"post-update-cmd": [
"Illuminate\\Foundation\\ComposerScripts::postUpdate",
"php artisan app:update",
"php artisan optimize"
]
これでcomposer install (update) --no-dev
を実行した時には、ide-helperのCommandは制御されます。
その他利用するrequire-devパッケージにartisanコマンド依存のものがあっても、上記のfunction handle()
に追加する事で対応するができますね。
このテクニックはLaracatsを参考にしました。
※ .envへ新たにキー登録をしていますが、APP_ENVがstaging, productionなどの値を使用した判定でも問題ありません。