誰しも、composer create-project laravel/laravelのコマンドで新規のLaravelのプロジェクトの開発を開始します。Laravelが凄いのは、この実行後にすぐにプロジェクトを立ち上げて(php artisan serve)ブラウザでサイトを閲覧することが可能となることです。その実行では画面に英語でいろいろと経過が表示されますが、いったい何が起こっているのでしょうか?

Laravelの新規のプロジェクトの作成

最新のLaravel 11.xを使用してプロジェクトを作成するには、以下のようなコマンドの実行が必要です。

$ composer create-project laravel/laravel laravel-11x

上のコマンドラインにおいて、

  • create-projectは、composerの新規プロジェクト作成のオプション名です。
  • laravel/laravellは、プロジェクトのルートとなるパッケージ名です。
    指定したパッケージ名をpackagist.orgのサイトでで探します。
    https://packagist.org/?query=laravel/laravel
    マッチするパッケージが存在するgithubのレポからパッケージのダウンロードとなります。
  • laravel-11xは新規プロジェクト名で、その名前でプロジェクトのディレクトリを作成して、そこに必要なパッケージをダウンロードしてインストールし設定を行います。

ルートパッケージのバージョンの指定も以下のように可能です。

$ composer create-project laravel/laravel laravel-10x "10.*" 

上では、 10.*は、Laravel 10で一番最新のバージョンで新規プロジェクトが作成されます。

プロジェクト作成の設計図

今回の新規のプロジェクトの作成として指定されるlaravel/laravelは、以下からダウンロードされます。
https://github.com/laravel/laravel
そこに含まれる、composer.jsonのファイルに、プロジェクトに必要なパッケージのダウンロードとインストール、そしてプロジェクト立ち上げに必要な.envやDBの作成などが指定されています。

ファイルの中身を見てみましょう。phpのプロジェクトですがフォーマットは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"
    },
...
    "scripts": {
        "post-autoload-dump": [
            "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
            "@php artisan package:discover --ansi"
        ],
        "post-update-cmd": [
            "@php artisan vendor:publish --tag=laravel-assets --ansi --force"
        ],
        "post-root-package-install": [
            "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "@php artisan key:generate --ansi",
            "@php -r \"file_exists('database/database.sqlite') || touch('database/database.sqlite');\"",
            "@php artisan migrate --graceful --ansi"
        ],
        "dev": [
            "Composer\\Config::disableProcessTimeout",
            "npx concurrently -c \"#93c5fd,#c4b5fd,#fb7185,#fdba74\" \"php artisan serve\" \"php artisan queue:listen --tries=1\" \"php artisan pail --timeout=0\" \"npm run dev\" --names=server,queue,logs,vite"
        ]
    },
...
}

上において、“require”は、laravelのルートパッケージがライブの環境で必要なパッケージです。“require-dev”は、開発環境で必要なパッケージです。たったこれだけですが、前回に説明したようにそれらが依存するパッケージがあるので実際にインストールパッケージは100以上の数になります。
“scripts”の部分は、特定なイベントごとに実行する指令が記述されています。

create-project実行の作業

composer create-projectを実行すると、以下のような経過表示となります。すべて掲載するととても長いのでパッケージのLockingやDownloadingやInstallingの多くは割愛しています。

上から順番に説明していきます。

プロジェクトディレクトリの作成

Creating a "laravel/laravel" project at "./laravel-11x"

まず、コマンド実行で指定した新規プロジェクト名のディレクトリlaravel-11xを作成します。

ルートパッケージのインストール

Creating a "laravel/laravel" project at "./laravel-11x"
Installing laravel/laravel (v11.3.3)
  - Downloading laravel/laravel (v11.3.3)
  - Installing laravel/laravel (v11.3.3): Extracting archive
Created project in /var/www/repos/laravel-11x

laravel/laravelが管理されているgithubのレポからファイルをダウンロードしてlaravel-11xのディレクトリにインストールします。
Downloadingでは、ダウンロードされたファイルは直接larave-11xへのディレクトリには置かれません。将来のインストールを効率化するために、ユーザーのキャッシュのディレクトリにインストールされます。私のubuntuの環境では、ホームディレクトリの.cache/composerにファイルが置かれます。すでに同じバージョンのパッケージがあるなら、Downloadingは行われずに、そのキャッシュのディレクトリから、laravel-11xへのディレクトリにファイルがコピーされます。その作業がInstallingです。

.envの作成

> @php -r "file_exists('.env') || copy('.env.example', '.env');"

これは、composer.jsonの“scripts”セクションにあった、“post-root-package-install”のスクリプトですね。.env.exampleをコピーして.envを作成です。

composer.lockの作成

Loading composer repositories with package information
Updating dependencies
Lock file operations: 107 installs, 0 updates, 0 removals
  - Locking brick/math (0.12.1)
  - Locking carbonphp/carbon-doctrine-types (3.2.0)
...
Writing lock file

ここでは、composer.jsonの“require”“require-dev”で指定されたパッケージたちのcomposer.jsonを読み、それらが依存するパッケージのcomposer.jsonも読み、コンフリクトがないようにインストールするすべてのパッケージとそのバージョンを決定します。そして、この時点で初めてcomposer.lockのファイルを作成して決定した情報を書き込みします。それがLockingの作業です。

“require”で指定したバージョンのデータと実際にダウンロードされるバージョンの違いに注意してください。
例えば、”require”では、“laravel/framework”: “^11.9”とありますが、この時点では

...
- Locking laravel/framework (v11.34.2)
...

と、v11.34.2のバージョンがインストールされます。

依存するパッケージのインストール

Installing dependencies from lock file (including require-dev)
Package operations: 107 installs, 0 updates, 0 removals
  - Downloading doctrine/inflector (2.0.10)
  - Downloading doctrine/lexer (3.0.1)
...
  - Installing doctrine/inflector (2.0.10): Extracting archive
  - Installing doctrine/lexer (3.0.1): Extracting archive
...
41 package suggestions were added by new dependencies, use `composer suggest` to see details.

ここのステップでルートパッケージに依存するすべてのパッケージがcomposer.lockに従ったバージョンでlaravel-11x/vendorにインストールされます。DownloadingInstallingはルートパッケージのところで説明したものと同様です。

scriptsの実行

Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi
> @php artisan vendor:publish --tag=laravel-assets --ansi --force
> @php artisan key:generate --ansi
> @php -r "file_exists('database/database.sqlite') || touch('database/database.sqlite');"
> @php artisan migrate --graceful --ansi

残りの作業は、composer.jsonで指定されたイベントにマッチするスクリプトが実行されます。
上から順番に以下のイベントとなります。

  •         "post-autoload-dump": [
                "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
                "@php artisan package:discover --ansi"
            ],
    

    composer autoload-dumpを実行したときにも実行されますが、プロジェクトの初期化で使用される必要なパッケージとそのクラスのリストを含むファイルを作成します。

  •         "post-update-cmd": [
                "@php artisan vendor:publish --tag=laravel-assets --ansi --force"
            ],
    

    プロジェクトで必要なアセットのファイルをパブリッシュします。上の経過では何もパブリッシュするものがなかったようです。

  •        "post-create-project-cmd": [
                "@php artisan key:generate --ansi",
                "@php -r \"file_exists('database/database.sqlite') || touch('database/database.sqlite');\"",
                "@php artisan migrate --graceful --ansi"
            ],
    

    最後に、ここで.envAPP_KEYの値を作成し、sqliteのデータベースのファイルを作成して、マイグレーションを実行します。

    上は最新のLaravel 11.xですが、Laravel 10.xでは、

            "post-create-project-cmd": [
                "@php artisan key:generate --ansi"
            ]
    

    となっていて、sqliteのデータベースの作成や設定は行いませんでした。

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

By khino