【入門編】Composerの依存関係解決エンジンをハック:–prefer-sourceと–prefer-distを環境別に使い分ける極意 – ビルド・パッケージ管理ツール生産性向上バイブル

こんにちは!開発現場で日々コードと向き合っていると、ふと「あれ、なんでパッケージのインストールにこんなに時間がかかるんだろう?」とか、「ライブラリのソースコードをちょっと書き換えてデバッグしたいのに、VENDORフォルダの中身だから直接いじれない…」なんてモヤモヤを感じたことはありませんか?

今回は、PHPのパッケージ管理における心臓部、Composerの依存関係解決エンジンを深くハックしていきましょう。

特に、現場で意外と見落とされがちな `–prefer-source` と `–prefer-dist` という2つのオプションを取り上げます。「なんとなくデフォルトのまま使っている」という方にこそ、この違いを完全に理解してほしいのです。これをマスターすれば、CI/CDパイプラインの爆速化や、複雑なバグ調査時のストレスフリーなデバッグ運用が手に入り、毎日のコーディングが劇的に楽になりますよ。

それでは、初心者の方にもすんなり本質が伝わるよう、基礎の基礎からアーキテクト視点の裏技まで、優しく紐解いていきましょう。

—

1. Composerとは何か?(その役割と基礎のキソ)

PHPで開発をする際、世の中の優秀なライブラリ(例えば、ルーティング機能やデータベース接続機能など)をゼロから全て自分で書く人はいませんよね。それらを安全かつ効率的に集めて管理してくれるのが Composer です。

Composerの役割は、いわば「あなたのプロジェクトの優秀な物流管理マネージャー」です。
「このライブラリのバージョン2.0が必要で、それが動くためには別のあのライブラリも必要で…」という複雑なパズル(依存関係)を自動的に計算し、整えてくれます。

最速のインストールと基礎セットアップ

まずは、あなたの手元でComposerが動く状態を確認しましょう。すでに導入済みの方も、最新の状態にアップデートするつもりで見てみてください。

ターミナルを開き、以下のコマンドを順に実行します。

公式サイトから安全にComposerのインストーラーを取得し、phpで実行してローカルに配置します
php -r “copy(‘https://getcomposer.org/installer’, ‘composer-setup.php’);”

インストーラーが改ざんされていないかハッシュ値(SHA-384)を検証します
php -r “if (hash_file(‘sha384’, ‘composer-setup.php’) === ‘e21205b207c3ff031906575712edab6f13eb0b361f2085f1f1237b7126d785e826a450292b1cfd1d6c8a325568c7c41f’) { echo ‘Installer verified’; } else { echo ‘Installer corrupt’; unlink(‘composer-setup.php’); } echo PHP_EOL;”

composer.phar(実行ファイル)をシステム全体で使えるように移動します
sudo php composer-setup.php –install-dir=/usr/local/bin –filename=composer

不要になったインストーラーファイルを削除します
php -r “unlink(‘composer-setup.php’);”

正しくインストールできたか、バージョンを確認してみましょう。

composer –version
期待される出力例: Composer version 2.x.x …

これで準備は完了です!

—

2. 精度高い「Hello World」的動作確認:最小限のプロジェクトを作ろう

Composerの動きを目で見える形で理解するために、超シンプルなプロジェクトを立ち上げてみます。

任意のディレクトリに移動し、作業用フォルダを作成してください。

mkdir composer-lab
cd composer-lab

ここに、Composerの心臓部である設計図 `composer.json` を作成します。今回は、PHPの便利なユーティリティ関数が集まった `symfony/string` という軽量なパッケージを導入してみましょう。

{
“name”: “developer/lab”,
“description”: “Composer prefer-source and prefer-dist laboratory”,
“require”: {
“symfony/string”: “^6.4”
}
}

  • `require`: このプロジェクトが動くために絶対にないと困る外部ライブラリ(本番用)を定義するブロックです。

では、この設計図をもとに、いよいよパッケージをインストールしてみます。ここで今回のメインテーマである `–prefer-dist` が登場します。

composer install –prefer-dist

実行結果のログ(イメージ):

Installing dependencies from lock file
Verifying lock file contents can be installed on current platform
Package operations: 2 installs, 0 updates, 0 removals

  • Downloading symfony/polyfill-ctype (v1.31.0)
  • Downloading symfony/string (v6.4.12)

Generating autoload files

おめでとうございます!これで `vendor/` ディレクトリが生成され、ライブラリが使えるようになりました。
では、実際に動くか確認するPHPファイル(`index.php`)を書いてみましょう。

slug();

echo “変換前: Hello, Composer Hackers! Let us dive deep.\n”;
echo “変換後: ” . $slug . “\n”;

実行してみます。

php index.php
出力結果:
変換前: Hello, Composer Hackers! Let us dive deep.
変換後: hello-composer-hackers-let-us-dive-deep

見事にライブラリが機能し、文字列が変換されました!これがComposerを使った開発の基本形です。

—

3. エンジニアの核心:「–prefer-source」と「–prefer-dist」の内部挙動と違い

さて、ここからが本題、アーキテクトとしての真骨頂です。
先ほど何気なく使った `–prefer-dist` と、もう一つのオプションである `–prefer-source` は、内部で一体何をしているのでしょうか?

–prefer-dist (ディストリビューション優先:デフォルト)

  • 内部挙動: GitHub等のリポジトリから、余計なテストコードやGit履歴を削ぎ落とした軽量な「ZIPアーカイブ」をダウンロードし、解凍して配置します。
  • メリット: ダウンロードが圧倒的に速く、ファイルサイズも小さいため、ネットワーク帯域を圧迫しません。
  • デメリット: 単なる「ファイルの束」としてダウンロードされるため、`vendor/` の中にあるライブラリのコードを書き換えても、Gitの管理下に置くことができません(パッチを当ててコミットするといった芸当が不可能)。

–prefer-source (ソースコード優先)

  • 内部挙動: パッケージの元となるGitリポジトリを直接クローン(`git clone`)し、内部でGitのサブモジュールや特定コミットの状態にチェックアウトします。さらに、`.git` ディレクトリがそのまま残ります。
  • メリット: ライブラリのソースコード内部に直接Gitの履歴が存在するため、その場でバグを見つけて修正し、自分のブランチとしてパッチ(Git差分)を切ったり、元のリポジトリにPull Requestを送るような開発がその場で可能になります。
  • デメリット: Gitの履歴やメタデータごと取得するため、ダウンロードに時間がかかり、ディスク容量も消費します。

—

4. 現場でどう使い分ける?:環境別・極意のアーキテクチャ

この2つの違いを理解したあなたなら、環境ごとにどちらを選ぶべきか、もうお気づきでしょう。現場で震えるほど役立つ使い分けの基準を伝授します。

① CI/CD環境・本番サーバー(Production / CI)

選ぶべきオプション: `–prefer-dist` (またはオプションなしのデフォルト)

  • 理由: CI(GitHub ActionsやGitLab CIなど)や本番サーバーでは、ライブラリのソースコードを「改造」することは絶対にありません。必要なのは「一刻も早く、正確なバージョンのコードを配置してビルドを完了させること」です。
  • 知見: さらにCI環境では、`composer install` の実行時間を短縮するため、`vendor/` ディレクトリ自体をキャッシュする仕組みを組み合わせます。

GitHub Actionsでの爆速キャッシュ&インストール設定の例

  • name: Cache Composer dependencies

uses: actions/cache@v3
with:
path: vendor
key: ${{ runner.os }}-composer-${{ hashFiles(‘/composer.lock’) }}
restore-keys: |
${- runner.os }}-composer-

  • name: Install Dependencies

run: composer install –prefer-dist –no-progress –no-interaction

`–no-progress` や `–no-interaction` を組み合わせることで、余計な画面描画を省き、CIの実行時間を数秒単位で削り取ることができます。

② ローカル開発環境 & ライブラリのバグ調査・パッチ当て(Local / Debugging)

選ぶべきオプション: `–prefer-source`

  • 理由: 「あれ、使っている外部ライブラリのこのメソッド、なんか挙動おかしくないか?」という場面に遭遇したことはありませんか?通常、`vendor/symfony/string` の中身を書き換えても、次に `composer update` を走らせた瞬間にすべて上書きされて消滅します。
  • 知見: しかし、あらかじめ `–prefer-source` でインストールしておけば、`vendor/symfony/string` は独立したGitリポジトリとして存在します。そのため、そのディレクトリに移動して自由に実験用コードを差し込んだり、ローカルでパッチを当てて検証することが劇的に簡単になります。

例:ローカルで特定のライブラリをソースコード(Gitクローン)として強制インストールする
composer require symfony/string –prefer-source

実際に `vendor/symfony/string` ディレクトリに入って `git status` を叩いてみてください。なんと、ちゃんとGitのワーキングツリーとして認識される感動を味わえます。

—

5. まとめ:今日からあなたの開発が変わる

今回は、Composerの依存関係解決エンジンにおける `–prefer-source` と `–prefer-dist` の決定的な違いと、それを環境ごとに最適に使い分けるアーキテクチャの極意をお伝えしました。

  • 本番やCIは、スピードと軽量さを重視して `–prefer-dist`
  • ローカルでの深いデバッグや、OSSのライブラリにパッチを当てて検証したいときは `–prefer-source`

この選択の意図をチーム全体で共有できるようになると、ビルドの待ち時間が減るだけでなく、「ライブラリのバグに直面しても恐れない、自立したエンジニアリング組織」へと一歩近づくことができます。

これをマスターしたあなたなら、明日からのパッケージ管理がもっと楽しく、ロジカルになるはずです。快適なComposerライフをエンジョイしてください!

タイトルとURLをコピーしました