LoginSignup
83
75

More than 3 years have passed since last update.

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

Last updated at Posted at 2017-04-25

環境

  • 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に環境変数を追加します
sample.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などの値を使用した判定でも問題ありません。

83
75
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
83
75