4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

LaravelAdvent Calendar 2019

Day 20

laravel newは何をやっているか?(あるいは何をやっていないか?)

Posted at

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のコマンドは読めると思います
まずは大雑把に見ていくと

  1. オプションを初期化
  2. ZIP拡張モジュールがロードされているかチェック
  3. 作成するプロジェクト名を退避して既存のプロジェクトがないかチェック
  4. アプリケーションの雛形をダウンロードしてカレントディレクトリに展開
  5. composerコマンドを実行準備
  6. 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

laravel newコマンドがやっていることまとめ

  1. プロジェクトの雛形となるZIPファイルをダウンロード
    1. ZIPモジュールがロードされていることが前提条件
    2. 最新のdevelop、認証機能を追加でインストールしたい場合はオプションを指定する必要がある
  2. composerに定義されたスクリプトを実行する
    1. composer installの実行
    2. .envファイルの作成
    3. 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`をバックエンドで走らせるなりで開発していくことになるでしょう

まとめ

  1. プロジェクトの最新の雛形からbuilt-in-serverが動く最低限の準備を行う
    1. LaravelのVersion指定はできない
    2. 認証機能が欲しい場合は--authを指定する
    3. masterでなくdevelopを使いたい場合は--devを指定する
  2. DBの作成は行わない、authオプションを指定した場合はmigrationを用いる
  3. フロントエンドのファイル構成は準備しない、ディレクトリ構成を準備したい場合はnpm run devを行う
    1. デフォルトではVue.js
    2. Reactを使いたい場合はphp artisan preset reactを用いてから

最後に

この記事を書こうと思ったのは11月からReactのプロジェクトに参加していてcreate-react-appを勉強がてら読んだことがきっかけでした
ReactもVueもアドベントカレンダーが空いてなかったのでlaravel newについて書きましたが、知らないこともいっぱいあってよい学びとなりました
PresetCommandなんかは今回色々と調べていて初めて存在を知ったくらい

ここしばらくコマンドの内容を理解せずに使うことが増えてしまっていましたが、よくない傾向なので改めて内容を理解して使う意識を持ちたいと思います
自分の知らないことを知るよい機会にもなるのでよく使うコマンドのリーディングは貴重な経験となりますね

4
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?