laravel newは何をやっているか?(あるいは何をやっていないか?)
この記事は Laravel Advent Calendar 2019 の20日目の記事です
そもそもlaravel newとは何か?
laraval newは新規にLaravelのプロジェクトを立ち上げる際にディレクトリ構成等を作ってくれるコマンド
使い方
composerはインストール済みであることを前提として進めます
$ composer global require laravel/installer
$ laravel new SOME_PROJECT
結果、下記の構成のディレクトリが出来上がります。ここからLaravelのプロジェクトを作っていくことになります
この時点で動かすだけならphp artisan serve
すればビルトインサーバーが立ち上がる状態となっています
$ tree -a -L 1
.
├── .editorconfig
├── .env
├── .env.example
├── .gitattributes
├── .gitignore
├── .styleci.yml
├── README.md
├── app
├── artisan
├── bootstrap
├── composer.json
├── composer.lock
├── config
├── database
├── package-lock.json
├── package.json
├── phpunit.xml
├── public
├── resources
├── routes
├── server.php
├── storage
├── tests
├── vendor
└── webpack.mix.js
本題のlaravel newは何をやっているか?
こちらのファイルがコマンドの実体となります
上記のコマンドはSymphonyのCLIを経由してsrc配下のファイルをキックします
NewCommand.phpは何をしているか見ていく
Laravelのコマンドを自作したことがあれば元になっているSymphonyのコマンドは読めると思います
まずは大雑把に見ていくと
- オプションを初期化
- ZIP拡張モジュールがロードされているかチェック
- 作成するプロジェクト名を退避して既存のプロジェクトがないかチェック
- アプリケーションの雛形をダウンロードしてカレントディレクトリに展開
- composerコマンドを実行準備
-
5で準備していたcomposerコマンドを実行
と、この様な流れになっています。見ておくべき箇所は4と6の箇所、オプションという意味では次点で1も重要といったところでしょうか
オプションを確認する
まずはコマンドラインのヘルプを参照します
$ laravel new --help
Description:
Create a new Laravel application
Usage:
new [options] [--] [<name>]
Arguments:
name
Options:
--dev Installs the latest "development" release
--auth Installs the Laravel authentication scaffolding
-f, --force Forces install even if the directory already exists
-h, --help Display this help message
-q, --quiet Do not output any message
-V, --version Display this application version
--ansi Force ANSI output
--no-ansi Disable ANSI output
-n, --no-interaction Do not ask any interactive question
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
続けてコマンドで定義しているオプションを確認します
protected function configure()
{
$this
->setName('new')
->setDescription('Create a new Laravel application')
->addArgument('name', InputArgument::OPTIONAL)
->addOption('dev', null, InputOption::VALUE_NONE, 'Installs the latest "development" release')
->addOption('auth', null, InputOption::VALUE_NONE, 'Installs the Laravel authentication scaffolding')
->addOption('force', 'f', InputOption::VALUE_NONE, 'Forces install even if the directory already exists');
}
コマンド側で定義しているのは引数nameと下記のオプションだけということがわかります
- dev
- auth
- force
じゃ、他のオプションはどこで定義されているのかっていうと、symphony/consoleのデフォルトオプションで定義されています
各オプションの意味は下記です
オプション | 意味 |
---|---|
--dev | masterでなく、developブランチの最新からプロジェクトを作成する |
--auth | 認証機能を備えたプロジェクトを作成する |
--force | 既存の同名ディレクトリがあってもプロジェクトを作成する |
--authオプションで作成した場合の差異
Laravelで用意された認証機能が使える状態でプロジェクトが作成されます
--auth
を使わないプロジェクトのroutesがこちら
+--------+----------+----------+------+---------+--------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+----------+----------+------+---------+--------------+
| | GET|HEAD | / | | Closure | web |
| | GET|HEAD | api/user | | Closure | api,auth:api |
+--------+----------+----------+------+---------+--------------+
一方、--auth
オプションを使ったプロジェクトのroutesはこちらとなります
+--------+----------+------------------------+------------------+------------------------------------------------------------------------+--------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+----------+------------------------+------------------+------------------------------------------------------------------------+--------------+
| | GET|HEAD | / | | Closure | web |
| | GET|HEAD | api/user | | Closure | api,auth:api |
| | GET|HEAD | home | home | App\Http\Controllers\HomeController@index | web,auth |
| | GET|HEAD | login | login | App\Http\Controllers\Auth\LoginController@showLoginForm | web,guest |
| | POST | login | | App\Http\Controllers\Auth\LoginController@login | web,guest |
| | POST | logout | logout | App\Http\Controllers\Auth\LoginController@logout | web |
| | GET|HEAD | password/confirm | password.confirm | App\Http\Controllers\Auth\ConfirmPasswordController@showConfirmForm | web,auth |
| | POST | password/confirm | | App\Http\Controllers\Auth\ConfirmPasswordController@confirm | web,auth |
| | POST | password/email | password.email | App\Http\Controllers\Auth\ForgotPasswordController@sendResetLinkEmail | web |
| | GET|HEAD | password/reset | password.request | App\Http\Controllers\Auth\ForgotPasswordController@showLinkRequestForm | web |
| | POST | password/reset | password.update | App\Http\Controllers\Auth\ResetPasswordController@reset | web |
| | GET|HEAD | password/reset/{token} | password.reset | App\Http\Controllers\Auth\ResetPasswordController@showResetForm | web |
| | GET|HEAD | register | register | App\Http\Controllers\Auth\RegisterController@showRegistrationForm | web,guest |
| | POST | register | | App\Http\Controllers\Auth\RegisterController@register | web,guest |
+--------+----------+------------------------+------------------+------------------------------------------------------------------------+--------------+
forceオプションは前のプロジェクトの内容を消してしまうのか?
消しません。あくまで上書きとなります
--force
オプションで行うことはあくまで既存の同名ディレクトリが存在するかのチェックを行わないことのみです
使い方としては既存のプロジェクトに最新のLaravelをインストールすることでしょうか?
アプリケーションの雛形をダウンロード
下記のいずれかのファイルをダウンロードする
devオプションとauthオプションは排他の様ですね
composerコマンドを実行
PROJECT_ROOT/.composer.jsonのscriptディレクティブのコマンドが実行されます
実行されるコマンドは下記の4つ
$ composer install --no-scripts
$ composer run-script post-root-package-install
$ composer run-script post-create-project-cmd
$ composer run-script post-autoload-dump
本記事執筆時点では上記のスクリプトの内容は下記となっています
"scripts": {
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover --ansi"
],
"post-root-package-install": [
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"@php artisan key:generate --ansi"
]
}
実行されるcomposerコマンドを見ていく
-
composer install
- script実行(後続の処理)を行わずに必要なパッケージをインストール
-
composer run-script post-root-package-install
- .envファイルがなければ.envをコピーして作成
-
composer run-script post-create-project-cmd
- APP_KEYを作成
-
composer run-script post-autoload-dump
- 自動的に
bootstrap/cache/packages.php
にProvidor登録されたパッケージを表示 - 詳しく’知りたい方は[こちら]を参照してください(https://readouble.com/laravel/6.x/ja/packages.html)を参照してください
- 自動的に
laravel newコマンドがやっていることまとめ
- プロジェクトの雛形となるZIPファイルをダウンロード
- ZIPモジュールがロードされていることが前提条件
- 最新のdevelop、認証機能を追加でインストールしたい場合はオプションを指定する必要がある
- composerに定義されたスクリプトを実行する
-
composer install
の実行 - .envファイルの作成
- APP_KEYの作成
-
laravel newがやっていないこと
- DBの準備、具体的にはuserテーブルの作成
- 必要な場合は
database/migration
を用いて作成する
- 必要な場合は
- LaravelのVersionを指定したプロジェクトの作成
- 指定をする必要がある経験者はcomposer.jsonを持っているだろうということでしょう
- 逆に新規は極力、最新のLaravelを使った方がよいという判断かと思います
- フロントエンドのディレクトリ構成(React || Vue)の作成
- 5.7の頃はVueのサンプルコードが入っていた記憶があるんですが、Reactとの選択式になったということかな?
- Vueを使う場合は下記を実行すれば、Vueのサンプルコンポーネントが作成されます(npmを使う場合)
$ npm install
$ npm run dev
Reactを使う場合は下記を実行します
$ php artisan preset react
$ npm install
$ npm run dev
artisan preset
は[none, bootstrap, vue, react]の4種に対応しますが、ここではnoneとbootstrapは読み飛ばします
artisan presetがやっていること
ArtisanServiceProvider.phpに定義があります
protected function registerPresetCommand()
{
$this->app->singleton('command.preset', function () {
return new PresetCommand;
});
}
- [STUBディレクトリ](https://github.com/laravel/framework/tree/6.x/src/Illuminate/Foundation/Console/Presets)配下からテンプレートを読み込み、package.json等のファイルを指定されたライブラリ向けに変更する
- PresetCommandの実体は[こちら](https://github.com/laravel/framework/blob/6.x/src/Illuminate/Foundation/Console/PresetCommand.php)
- 上記の書き換えにより必要なファイルのインストール準備が整い、`npm run dev`でコンパイルされることでフロントエンドの開発準備が整います
- 後は`npm run watch`をバックエンドで走らせるなりで開発していくことになるでしょう
まとめ
- プロジェクトの最新の雛形からbuilt-in-serverが動く最低限の準備を行う
- LaravelのVersion指定はできない
- 認証機能が欲しい場合は
--auth
を指定する - masterでなくdevelopを使いたい場合は
--dev
を指定する
- DBの作成は行わない、authオプションを指定した場合はmigrationを用いる
- フロントエンドのファイル構成は準備しない、ディレクトリ構成を準備したい場合は
npm run dev
を行う- デフォルトではVue.js
- Reactを使いたい場合は
php artisan preset react
を用いてから
最後に
この記事を書こうと思ったのは11月からReactのプロジェクトに参加していてcreate-react-app
を勉強がてら読んだことがきっかけでした
ReactもVueもアドベントカレンダーが空いてなかったのでlaravel newについて書きましたが、知らないこともいっぱいあってよい学びとなりました
PresetCommandなんかは今回色々と調べていて初めて存在を知ったくらい
ここしばらくコマンドの内容を理解せずに使うことが増えてしまっていましたが、よくない傾向なので改めて内容を理解して使う意識を持ちたいと思います
自分の知らないことを知るよい機会にもなるのでよく使うコマンドのリーディングは貴重な経験となりますね