LaravelでComposerを触る現実と安全手順

Laravelでライブラリを追加する=結局Composerを触ることになります。つまり「パッケージを入れるだけ」の作業に見えて、実際は依存関係・PHPバージョン・拡張モジュール・オートロード・設定ファイル生成などが絡む“変更”です。だからこそ、最初に「安全な手順」と「壊れやすいポイント」を押さえるだけで、事故率が一気に下がります。

Laravelでライブラリ追加が“Composer作業”になる理由

Laravelは便利な枠組みですが、外部ライブラリを取り込む入口はComposerです。Laravel固有の機能(サービスプロバイダや設定publishなど)も、結局は「Composerで入れたパッケージ」を起点に動きます。

追加した瞬間に起きること(見えづらいが重要)

  • composer.json が変わる(依存の宣言が増える)
  • composer.lock が変わる(具体的な解決結果が固定される)
  • vendor/ 以下が変わる(実体が増える)
  • autoload の定義が更新される(PSR-4やファイル読み込み)
  • Laravel側の“自動検出”が走る場合がある(パッケージのdiscovery)

ここを理解していないと、チーム開発で「ローカルだけ動く」「CIだけ落ちる」の典型パターンにハマりやすいです。

まず押さえる結論:安全な追加手順の型

ライブラリ追加は、手順が決まっている作業です。毎回この型でやると、問題が起きても原因切り分けが簡単になります。

0) 追加前に確認するチェックリスト

  • PHPのバージョン(例:8.1 / 8.2 / 8.3)
  • Laravelのバージョン(例:10系 / 11系)
  • ext-xxx(必要なPHP拡張。例:ext-sodium, ext-intl)
  • 現在のcomposer.lockが最新か(Gitで差分がないか)
  • 実行環境(Docker/ローカル/CI)でPHP拡張が揃っているか

1) 追加は composer require で行う(手編集しない)

composer.json を直接編集してから install するより、requireの方が「バージョン解決・lock更新・エラーの文脈」が揃います。

composer require vendor/package

2) composer.lock は必ずコミットする

Laravelのアプリ開発(ライブラリ利用側)では、composer.lockをコミットするのが基本です。コミットしないと、環境ごとに入るバージョンがズレて再現性が落ちます。

3) 追加後に最低限やる動作確認(小さく検証)

  • artisan が動くか
  • ルート1本叩いてエラーが出ないか
  • テスト(あるなら)を1回流す
  • 本番と同等のPHP拡張を使う環境でCIを通す

4) それでも詰まったら「依存解決のログ」を読む

Composerは失敗時に理由を出します。慣れないうちは読みづらいですが、主に見たいのは以下です。

  • requires php ^8.2 のようなPHP制約
  • conflicts の行(衝突しているパッケージ)
  • replace / provide の行(置き換え関係)
  • locked to(lockされているバージョンが原因)

「ライブラリ追加で壊れがち」な3大ポイント

1) PHPバージョンと拡張モジュールが揃っていない

ローカルは8.3、CIは8.2、コンテナは8.1、みたいな状態だと、同じcomposer.lockでも動きが変わります。さらに、必要なPHP拡張がCIに入っていないケースも多いです。

php -v
php -m | sort
composer check-platform-reqs

注意点:composer check-platform-reqs は「今の環境で lock の要件を満たすか」を確認できます。CIに入れると、原因が早めに見えます。

2) composer.lock を更新したのに vendor を更新していない(または逆)

「lockだけ変えてvendor更新し忘れ」や「vendorだけ増えたがlock差分がない」などが混ざると、再現性が崩れます。基本は以下の運用で揃えるのが無難です。

  • 追加:composer require(lock更新+vendor更新)
  • 取得:composer install(lockに合わせてvendorを揃える)
  • 更新:composer update(範囲内でlockを更新する)

3) update を軽く打ってしまい、依存が雪崩れる

初心者がやりがちなのが、困ったら composer update を実行してしまうことです。updateは「許容範囲で一気に更新」なので、関係ないパッケージまで動いてしまうことがあります。

# どうしてもupdateするなら、対象を絞る
composer update vendor/package --with-all-dependencies

実務で効く:Composerの“事故らない”運用ルール

ルール1:追加と更新はPRを分ける

「新規追加」と「既存更新」を同じPRにすると、差分が読みづらくなりレビューが難しくなります。事故っても戻しづらいです。

ルール2:バージョン指定は“極端に固定しすぎない”

例えば `"1.2.3"` のように完全固定にすると、セキュリティ修正が入っても取り込みにくくなります。一方、`"*"` のように緩すぎると予期せぬ更新が混ざります。現場では次のような落としどころが多いです。

  • ^1.2(メジャーは固定、マイナーとパッチを許容)
  • ~1.2(マイナー固定、パッチを許容)

ルール3:Composerスクリプトが何をしているか把握する

composer.json の scripts に、post-install / post-update で何か実行しているプロジェクトもあります。ここを理解していないと「なぜか勝手に動く」が起きます。

{
  "scripts": {
    "post-install-cmd": [
      "@php artisan package:discover --ansi"
    ]
  }
}

よくある失敗例と、復旧の考え方

失敗例:ローカルで入ったのにCIで落ちる

原因候補はだいたい次のどれかです。

  • CIのPHP/拡張が違う
  • lockがコミットされていない
  • CIが composer install ではなく update をしている
  • private repository の認証がCIにない

復旧の基本は「CI環境で composer install を再現する」ことです。Dockerがあるなら、CIと同じイメージで install して差分を見ます。

失敗例:artisan が突然死ぬ(autoloadエラー)

オートロードやキャッシュが壊れていることがあります。まずはキャッシュを落として、再生成します。

php artisan optimize:clear
composer dump-autoload

どんな人に“Composerの理解”が効くか

Laravelを触っていて、次の状況が1つでもあるならComposerの理解は投資対効果が高いです。

  • チーム開発で、ローカルとCIの差分に悩んでいる
  • 依存追加のたびに怖くて手が止まる
  • Laravelのアップデートに挑戦したい
  • 監査やセキュリティ対応(脆弱性修正)を回したい

逆に、個人で小規模・短命の検証だけなら、深追いせず「安全手順の型」だけで十分なことも多いです。

まとめ:Composerは“触るな”ではなく“触り方を決める”

Laravelでライブラリ追加がComposer作業になるのは避けられません。ただ、手順を固定し、updateの扱いを慎重にし、環境差(PHP/拡張)を揃えるだけで、事故はかなり減ります。

結局のところ、Composerは「怖いもの」ではなく「変更の影響範囲を見える化してくれる道具」です。怖さの正体は、触ることではなく、触り方が毎回バラバラなことにあります。