Edited at

【Laravel】composer require-devの開発、本番での切り分け

More than 1 year has passed since last update.


環境


  • Laravel 5.1LTS

  • Composer 1.4


概要

Laravelを使用していて、require-devオプションに開発用パッケージを導入する事があるかと思います。

私の環境ですとrequire-devには以下のパッケージを記載しています


composer.json

"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の起動時にエラーとなります。


config/app.php

'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を実行した際にクラスが見つからずこちらもエラーになります。


composer.json

"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を別ファイルに分けます。

    ※ ファイル名やディレクトリは好きに変更してください


config/dev/app.php

'providers' => [

'Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider',
'Barryvdh\Debugbar\ServiceProvider',
],
'aliases' => [
'Debugbar' => 'Barryvdh\Debugbar\Facade',
],


  • .envに環境変数を追加します

REQUIRE_DEV=true


  • AppServiceProviderに以下を追記します


app/Providers/AppServiceProvider.php

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コマンドから実行できるクラスを作成します。


ComposerPostScripts.php

<?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に登録します。


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などの値を使用した判定でも問題ありません。