「Symfonyをインストール」するとき、具体的に何が行われているのか
Symfony Advent Calendar 2023 の1日目の記事です!🎄✨
Twitter (X) でもちょいちょいSymfonyネタを呟いてます!よろしければ フォロー お願いします!
はじめに
Symfonyアプリケーションの開発を始めるときに必ず行う「Symfonyをインストールする」という作業。
今日はこの「Symfonyをインストールする」という作業が具体的に何をすることなのか、裏で何が行われているのか、を改めておさらいしてみたいと思います。
公式ドキュメント では、Symfonyのインストール方法として、
# 伝統的なWebアプリケーションを作る場合
$ symfony new {ディレクトリ名} --version="{バージョン指定}" --webapp
# マイクロサービス、コンソールアプリケーション、APIなどを作る場合
$ symfony new {ディレクトリ名} --version="{バージョン指定}"
または
# 伝統的なWebアプリケーションを作る場合
$ composer create-project symfony/skeleton:"{バージョン指定}" {ディレクトリ名}
$ cd {ディレクトリ名}
$ composer require webapp
# マイクロサービス、コンソールアプリケーション、APIなどを作る場合
$ composer create-project symfony/skeleton:"{バージョン指定}" {ディレクトリ名}
という 2 x 2 パターンの方法が紹介されています。
これらについて詳しくみていきましょう。
composer create-project
コマンドでSymfonyをインストールすることの意味
順番が前後しますが、まずは後者の composer create-project
コマンドを使う方法について説明します。
composer create-project
コマンド は、公開されているパッケージの composer.json
をもとに新しくプロジェクトを作成するためのコマンドです。
「パッケージの composer.json
をもとに新しくプロジェクトを作成する」とは、以下の操作を行うこととほぼ同じ意味です。
- 新しくディレクトリを作成する
- 作成したディレクトリの直下に
composer.json
を作成し、パッケージのcomposer.json
の内容をコピペする - 作成したディレクトリの直下で
composer install
を実行する
「ほぼ同じ」と書いたとおり、厳密には、パッケージによっては上記の操作以上のことが行われることがあります。
例えば、パッケージの composer.json
の scripts
フィールドに post-create-project
イベント に対する処理が書かれている場合、その処理は composer install
時には実行されず、composer create-project
時にのみ実行されます。
例として、
koriym/php-skeleton
の実装(composer.json
、src/Installer.php
)などを読んでみると理解に助かると思います。
また、Symfony Flex を require
しているパッケージにおいて、composer.json
の flex-require
フィールドに依存パッケージが書かれている場合、それらの依存パッケージは composer create-project
時にのみインストールされるようです。
Symfony Flexについての詳細は以下の過去記事をご参照ください。
これらを踏まえて、公式ドキュメントで紹介されているコマンド
$ composer create-project symfony/skeleton:"7.0.*" my_project_directory
を実行すると何が起こるかを整理してみましょう。
まず、symfony/skeleton
パッケージの、7.0.*
というバージョン指定に適合する最新のバージョン(本稿執筆時点では 7.0.99
) が採択され、その composer.json
をもとにプロジェクトが作成されます。
その際、Symfony Flexの働きによって、composer.json
の flex-require
フィールドの中身 が require
に展開され、それらのパッケージもインストールされます。
各種パッケージがインストールされる際に、Symfony Flexの働きによって、symfony/framework-bundle
を始めとする Symfony Recipesリポジトリ にレシピを持つパッケージのレシピがインストールされます。
これにより、いわゆるSymfonyの標準的なディレクトリ構造やデフォルトの設定ファイル群を備えたプロジェクトが作成され、「Symfonyがインストールされた」状態になるというわけです💡
symfony new
コマンドでSymfonyをインストールすることの意味
次に、symfony new
コマンドを使う方法について説明します。
symfony new
コマンドは、Symfony CLI で利用できるサブコマンドです。
Symfony CLIは、
- Symfonyをインストールする機能(つまり
symfony new
コマンド) - TSL証明書のサポートもある、強力なローカルWebサーバー機能
- セキュリティの脆弱性をチェックする機能
- Platform.sh とのシームレスな統合
などの機能を持つ、Symfonyアプリケーションの開発環境になくてはならないツールです。
公式ドキュメントで紹介されている symfony new
によるSymfonyのインストールコマンドは
$ symfony new my_project_directory --version="7.0.*"
です。これを実行すると何が起こるかというと、実は
$ composer create-project symfony/skeleton:"7.0.*" my_project_directory
を実行するのとまったく同じです。
symfony new
コマンドの実装を覗いてみると分かりますが、内部的には composer create-project symfony/skeleton
を実行しているだけ なのです。
なので、composer create-project symfony/skeleton
コマンドを使う方法も、symfony new
コマンドを使う方法も、得られる結果は完全に同一です。どっちを使っても構いません👌
composer require webapp
や --webapp
の意味
最後に、2 x 2 パターンの残りの半分、
# 伝統的なWebアプリケーションを作る場合
$ symfony new {ディレクトリ名} --version="{バージョン指定}" --webapp
# 伝統的なWebアプリケーションを作る場合
$ composer create-project symfony/skeleton:"{バージョン指定}" {ディレクトリ名}
$ cd {ディレクトリ名}
$ composer require webapp
これらについて説明します。
まずは symfony new
コマンドの実装を再度覗いてみましょう。--webapp
オプションを付けた場合には追加で composer require webapp
を実行するようになっている ことが分かります。
つまり、やはりここでも symfony new
コマンドのパターンと composer create-project
コマンドのパターンで、実は起こることは同じというわけです。
では、composer require webapp
を実行すると何が起こるのでしょうか。
そもそも、webapp
というパッケージ名指定が少し不思議ですよね。packagist.org に公開されているパッケージはどれも ベンダー名/パッケージ名
という形式の名前になっていて、webapp
などという名前のパッケージは見つけられません。
それもそのはず、これはSymfony Flexの働きを前提としたパッケージ名指定なのです。Symfony Recipeseリポジトリに登録されている symfony/webapp-pack
のレシピ を見てみると、
{
"aliases": ["webapp"],
}
という記述が見られます。つまり、Symfony FlexがインストールされたComposer環境においては、webapp
というエイリアスを使って symfony/webapp-pack
パッケージ をインストールできるというわけです💡
symfony/webapp-pack
パッケージの composer.json
の内容 は以下のとおりです。
{
"name": "symfony/webapp-pack",
"type": "symfony-pack",
"license": "MIT",
"description": "A webapp pack on top of the default skeleton",
"require": {
"symfony/asset": "*",
"symfony/debug-pack": "*",
"symfony/doctrine-messenger": "*",
"symfony/expression-language": "*",
"symfony/form": "*",
"symfony/http-client": "*",
"symfony/intl": "*",
"symfony/mailer": "*",
"symfony/maker-bundle": "^1.0",
"symfony/mime": "*",
"symfony/monolog-bundle": "^3.1",
"symfony/notifier": "*",
"symfony/orm-pack": "*",
"symfony/process": "*",
"symfony/profiler-pack": "*",
"symfony/security-bundle": "*",
"symfony/serializer-pack": "*",
"symfony/string": "*",
"symfony/test-pack": "*",
"symfony/translation": "*",
"symfony/twig-pack": "*",
"symfony/validator": "*",
"symfony/web-link": "*"
},
"require-dev": {
"symfony/debug-pack": "*",
"symfony/profiler-pack": "*",
"symfony/maker-bundle": "^1.0",
"symfony/test-pack": "*"
},
"conflict": {
"symfony/framework-bundle": "<5.0"
}
}
要するに、各種Symfonyコンポーネントやバンドルをまとめてインストールするためのメタパッケージになっているわけです。
公式ドキュメントで # 伝統的なWebアプリケーションを作る場合
と注釈されていたのは、「伝統的なWebアプリケーションを作る場合なら、まあこれらのパッケージはほぼ使うでしょうから、一通りまとめて入れておくといいですよ」という意味だったわけですね。
とはいえここに列挙されているパッケージはすべてが常に必要なものとも言えないと思うので、webapp
ありでインストールした場合も、不要なものは手動で composer remove
する(か、そもそも webapp
なしでインストールしておいて必要なものを追加していくようにする)ことを個人的にはおすすめします。
おわりに
というわけで、「Symfonyをインストール」するとき、具体的に何が行われているのかを改めておさらいしてみました。
Symfonyに対する理解が少し深まりましたね!
Symfony Advent Calendar 2023、明日がさっそく空きになってしまっているので、ぜひどなたかご参加ください!!!ライトな記事でも全然いいと思います!!!
Discussion