今回は、composer.jsonでrequireやrequire-devにリストされるパッケージのバージョンに関して説明します。今まで気にもとめていなかった ^11.9などの意味を解明します。

composer.json

まず、前回の「composerをもっと知ろう(2)composer create-projectでは何が起こっている?」で記載したcomposer.jsonを再度見てみましょう。

{
    "name": "laravel/laravel",
    "type": "project",
    "description": "The skeleton application for the Laravel framework.",
    "keywords": ["laravel", "framework"],
    "license": "MIT",
    "require": {
        "php": "^8.2",
        "laravel/framework": "^11.9",
        "laravel/tinker": "^2.9"
    },
    "require-dev": {
        "fakerphp/faker": "^1.23",
        "laravel/pail": "^1.1",
        "laravel/pint": "^1.13",
        "laravel/sail": "^1.26",
        "mockery/mockery": "^1.6",
        "nunomaduro/collision": "^8.1",
        "phpunit/phpunit": "^11.0.1"
    },
...
}

"laravel/framework": "^11.9"のような記述があります。laravel/frameworkはパッケージ名で、^11.9はインストールするバージョンを指示していると思われますが、その記事を書いた時点では実際にインストールされたバージョンは11.34.2でした。どうして11.9ではないのでしょう。11.9の前についているキャレットはいったい何でしょう。

^11.9の意味

"laravel/framework": "^11.9"の意味を解明するには、laravel/frameworkのパッケージをローカル環境にインストールして、gitのタグを見る必要があります。

パッケージをインストールした後に、以下のコマンドを実行して、v11のみのタグを抽出します。

$ git tag --sort=v:refname | grep v11

コマンドの出力は、以下のようになります。長いので途中…で割愛と示しています。これを書いている時点では最新はv11.37.0です。

v11.0.0
v11.0.1
v11.0.2
v11.0.3
v11.0.4
v11.0.5
v11.0.6
v11.0.7
v11.0.8
v11.1.0
v11.1.1
v11.2.0
v11.3.0
v11.3.1
v11.4.0
v11.5.0
v11.6.0
v11.7.0
v11.8.0
v11.9.0
v11.9.1
v11.9.2
...
v11.36.1
v11.37.0

上において、タグの最初の数字がメージャーのバージョン番号で、それ以下はマイナーのバージョン番号です。
例えば、v11.37.0では、11がメジャーで37.0がマイナー。

Laravelの新規のプロジェクトを作成するときは、composer installが実行されます(この時点では、composer.lockのファイルはまだ存在しないと仮定)。プロジェクトにとってcomposer.jsonで指定されるパッケージはその時点で最新のパッケージのインストールを試みます。しかし必ずしもパッケージの最新とも限りません。例えば、Laravel 10.xをインストールするのに最新の11.xがインストールされては困ります。それゆえに、^11.9のような指定が使われます。

composer.json"laravel/framework": "^11.9"でのキャレットは、11.9以上で12.0.0未満のバージョンでその時点で最新のバージョンをインストールしなさい、という指示です。それゆえに、前回の記事を書いた時点では最新のv11.34.2が、この記事を書いている現時点ではv11.37.0がインストールされます。

この理解にとてもいいツールがありますので紹介します。

https://semver.madewithlove.com/?package=laravel%2Fframework&constraint=%5E11.9

上のリンクをクリックすると以下のような画面となります。

先ほどのlaravel/frameworkのパッケージで^11.9を指定したときにインストールされるバージョンのリストが赤箱でハイライト表示されます。そこで、^11.0とか^11.37とか入力してみてどれがハイライトされるか試してみてください。他のパッケージも指定してみてください。

さて、ここで不思議に思うはどうしてインストールすべきバージョンが最新の1つ(ここでは、v11.37.0)だけでなくいくつもハイライトされているのかです。v11.9.0からv11.37.0までのすべてのバージョンがハイライトされていますね。

これは共にインストールする他のパッケージとの依存があるかもしれないからです。もしかして、他のパッケージでは、laravel/frameworkへの依存があり、そのパッケージのcomposer.jsonにおいて、 "laravel/framework": "11.18.1"と1つのバージョン(バージョンの前にキャレットがない)のみを指定しているかもしれません。その場合はプロジェクトでインストールされるlaravel/frameworkのバージョンは11.18.1のみと制限されます。プロジェクトがインストールしたいバージョンと依存するパッケージがインストールしたいバージョンをともに満たすためにです。

composer.jsonで記載されるバージョンの形式には、他にも~11.9とか11.9.*とか^6.0|^7.0|^8.0|^9.0|^10.0|^11.0とかあります。以下で詳しい説明があります。
https://getcomposer.org/doc/articles/versions.md

composer.lock

composer installを最初に実行した後には、composer.lockのファイルが作成されます。これは、その名の通り、実行時にインストールされたすべてのパッケージのバージョンの情報が含まれています。次回に、違う環境(例えばライブ環境とか)でこのファイルがあれば、まったく同じバージョンでパッケージをインストールしてくれるので、異なる環境での同じバージョンのパッケージがインストールされることを保証してくれます。

メルマガ購読の申し込みはこちらから。

By khino