[Composer]開発と本番環境を分離する | A Day In The Boy's Life

A Day In The Boy's Life

とあるエンジニアのとある1日のつぶやき。

composerを使って管理するパッケージの中で、開発環境では必要だが本番では必要ないといったパッケージもあったりします。

例えば、テストツールのPHPUnitは開発環境では必要だけど本番ではいらないといった具合です。

こういった場合でも、composer.jsonをうまく書いてあげれば環境を分離して不要なパッケージを本番環境に導入せずに済んだりします。



開発環境で必要なパッケージを定義する


前回の[Composer] composer.jsonを読み解く にて、composerでインストールしたいパッケージはrequireキーの中にJSONの配列形式で記述すると書きましたが、require-devという項目も存在します。

文字通り、開発環境で必要なパッケージを定義するもので、デフォルトではこのrequire-devに指定したパッケージもインストール、更新の対象となります。


{
  "require": {
    "pear/pear_exception": "1.0.*@dev",
    "pear/log": "dev-master"
  },
  "require-dev": {
    "squizlabs/php_codesniffer": "dev-master",
    "phpunit/phpunit": "4.5.*"
  }
}

そのままupdateを実行するとrequireおよびrequire-devの両方がインストールされます。


$ composer show -i
doctrine/instantiator             1.0.4              A small, lightweight utility to instantiate objects in PHP without invoking their const...
pear/log                          dev-master df7aa17 PEAR Logging Framework
pear/pear_exception               1.0-beta1          The PEAR Exception base class.
phpdocumentor/reflection-docblock 2.0.4              
phpspec/prophecy                  1.4.0              Highly opinionated mocking framework for PHP 5.3+
phpunit/php-code-coverage         2.0.15             Library that provides collection, processing, and rendering functionality for PHP code ...
phpunit/php-file-iterator         1.3.4              FilterIterator implementation that filters files based on a list of suffixes.
phpunit/php-text-template         1.2.0              Simple template engine.
phpunit/php-timer                 1.0.5              Utility class for timing
phpunit/php-token-stream          1.4.0              Wrapper around PHP's tokenizer extension.
phpunit/phpunit                   4.5.1              The PHP Unit Testing framework.
phpunit/phpunit-mock-objects      2.3.1              Mock Object library for PHPUnit
sebastian/comparator              1.1.1              Provides the functionality to compare PHP values for equality
sebastian/diff                    1.3.0              Diff implementation
sebastian/environment             1.2.2              Provides functionality to handle HHVM/PHP environments
sebastian/exporter                1.2.0              Provides the functionality to export PHP variables for visualization
sebastian/global-state            1.0.0              Snapshotting of global state
sebastian/recursion-context       1.0.0              Provides functionality to recursively process PHP variables
sebastian/version                 1.0.5              Library that helps with managing the version number of Git-hosted PHP projects
squizlabs/php_codesniffer         dev-master f307928 PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a def...
symfony/yaml                      v2.6.6             Symfony Yaml Component

本番環境(require-devで指定したパッケージは不要)の場合は、下記のように実行します。


$ composer update --no-dev

$ composer show -i
pear/log            dev-master df7aa17 PEAR Logging Framework
pear/pear_exception 1.0-beta1          The PEAR Exception base class.

require-devのパッケージをインストールしてしまった場合でも、--no-devオプションをつけたら不要なパッケージは削除してくれます。

オプションの順番を変えて


$ composer --no-dev update

でも動いたりしますので、本番環境では省略したcomposerコマンドのAliasを作ってしまってもよいかもしれません。


ちなみに、--no-devオプションはオートロードでも有効になります。

本番環境と開発環境で読み込むライブラリが違うといった場合は、下記のように環境を分けることもできたりします。


{
  "autoload": {
    "psr-0": {
      "Foo\\Bar\\": "prod/lib/"
    },
    "classmap": [
      "prod/another_lib/Foo.class.php"
    ]
  },
  "autoload-dev": {
     "psr-0": {
     "Foo\\Bar\\": "dev/lib/"
    },
    "classmap": [
      "dev/another_lib/Foo.class.php"
    ]
  }
}

classmapで指定しているように本番(require)と開発(require-dev)で同一のクラスを読み込んでいる場合、デフォルトだとautoload-devのものがオートロードされます。

本番環境用にしたければ同じように--no-devオプションを付けます。

dump-autoloadでも使えます。


$ composer dump-autoload --no-dev


composer.jsonを環境ごとにうまく管理していけば同様のこともできたりもしますが、手間となったりミスがあった場合に余計なパッケージが導入されてしまうというリスクもあるため、うまく活用すれば管理が楽になるかもしれません。