laravel-modulesを使ってみた

# 概要

- laravel-modulesというライブラリを使ってみたので使った時のメモと導入方法を残す。

# できるようになること

- `app/Modules`直下に`app/`直下と近い構成のファイル群を生成して各モジュールごとに疎結合な開発をする事ができる。
- 最近流行り？のモジュラモノリスアプリケーションの構築に向いている。
    - モジュラモノリス
        - マイクロサービスがかなり難しいから、もうちょっと簡単に誰でも使えるようにした開発スタイル
        - ドメインごとにモジュールを分けて疎結合にするが、DBは一個
        - メリット
            - モジュールごとに疎結合なのでスパゲッティコードになりにくい。
            - いざマイクロサービスにしますぞ！ってなったときに切り出しやすい。
        - デメリット
            - DBは一個なのでモジュールをまたぐ外部キー制約などがあるとマイグレーションとかがちょっと面倒になるらしい。（教えていただきました。）

# 導入方法

1. 下記コマンドを実行してライブラリをインストールする。

    ```terminal
    $ composer require nwidart/laravel-modules
    ```

1. どうやらデフォルトでは当該のライブラリの　コードはautoloadされないようだ。composer.jsonを開き、`autoload`の箇所に下記の内容を追記する。

    ```composer.json
    "autoload": {
        "psr-4": {
            "App\\": "app/",
            "Modules\\": "Modules/",
            "Database\\Factories\\": "database/factories/",
            "Database\\Seeders\\": "database/seeders/"
        }
    },
    ```

1. 上記修正後、下記コマンドを実行して一回意図的にautoload　させる。

    ```terminal
    $ composer dump-autoload
    ```

# 使ってみる

1. 公式ドキュメントに沿って体験してみる。

### モジュールの作成

1. 下記コマンドを実行して「Blog」というモジュールを作成してみる。どうやらモジュールは`$ php artisan module:make モジュール名`で作成できるようだ。（モジュール名を半角スペース開けて羅列すれば一度に複数のモジュール作成が可能）

    ```terminal
    $ php artisan module:make Blog
    ```

1. `app/Modules`ディレクトリ直下にBlogディレクトリが作成され、その直下に`app/`とちょっと似ているファイル群が生成された。
1. モジュール作成時にコントローラーやデータベース系のファイルが自動生成されるがこれがいらない場合下記の様に`-p`もしくは`--plain`オプションをつけると良い。　（どのくらい差分が出るのかを試して、本記事後半の付録に記載したのでご参考程度に！）

    ```terminal
    $ php artisan module:make モジュール名 -p
    ```

### モジュールリスト取得

- 下記を実行することでモジュールの一覧を閲覧する事ができる。

    ```terminal
    $ php artisan module:list
    ```

### モデルクラスの作成

1. 下記を実行することでモジュール内にモデルクラスを作成する事ができる。

    ```terminal
    $ php artisan module:make-model モデルクラス名 モジュール名
    ```

1. 下記の様に`-m`オプションをつけることでモデルとマイグレーションファイルを一緒に作成する事ができる。

    ```terminal
    $ php artisan module:make-model -m モデルクラス名 モジュール名
    ```

### マイグレーションファイルの作成

- 下記を実行することでモジュール内にマイグレーションファイルを作成する事ができる。

    ```terminal
    $ php artisan module:make-migration マイグレーションファイル名 モジュール名
    ```

### マイグレーション・リフレッシュマイグレーション・ロールバックの実施

1. 下記を実行することでモジュール内のマイグレーションファイルをマイグレートする事ができる。（モジュール名を指定しない場合、すべてのモジュールのマイグレーションが行われる。）

    ```terminal
    $ php artisan module:migrate モジュール名
    ```

1. 下記を実行することでモジュール内のマイグレーションファイルをリフレッシュマイグレートする事ができる。（モジュール名を指定しない場合、すべてのモジュールのリフレッシュマイグレーションが行われる。 `--seed`オプションなども使用可能）

    ```terminal
    $ php artisan module:migrate-refresh モジュール名
    ```

1. 下記を実行することでモジュール内のマイグレーションファイルをロールバックする事ができる。（モジュール名を指定しない場合、すべてのモジュールのロールバックが行われる。）

    ```terminal
    $ php artisan module:migrate-rollback モジュール名
    ```

1. ！！！！！！注意！！！！！「リフレッシュマイグレーションができるならモジュール固有でフレッシュマイグレーションもできるだろう」と下記コマンドを実行するとモジュール外のマイグレーションもfresh実行されてしまうので実行しないほうが良いです。（よく考えたら、モジュール固有でフレッシュマイグレーションされてしまうとテーブル間で整合性取れなくなるから当たり前かも。。）

    ```terminal
    # 実行注意↓↓↓↓
    $ php artisan module:migrate-fresh モジュール名
    # 実行注意↑↑↑↑
    ```

### シードの作成と実行

1. 下記を実行することでモジュール内にシードを作成する事ができる。

    ```terminal
    $ php artisan module:make-seed シードファイル名 モジュール名
    ```

1.  下記を実行することモジュール内でシードを実行する事ができる。

    ```terminal
    $ php artisan module:seed モジュール名
    ```

### コントローラーの作成

- 下記を実行することでモジュール内にコントローラーを作成する事ができる。

    ```terminal
    $ php artisan module:make-controller コントローラー名 モジュール名
    ```

### ミドルウエアの作成

- 下記を実行することでモジュール内にミドルウエアを作成する事ができる。

    ```terminal
    $ php artisan module:make-middleware ミドルウエア名 モジュール名
    ```

### メールクラスの作成

- 下記を実行することでモジュール内にミドルウエアを作成する事ができる。

    ```terminal
    $ php artisan module:make-mail メールクラス名 モジュール名
    ```



### 使用中モジュールの固定・固定解除（筆者勝手に非推奨）

1. 下記を実行することで現在開発中のモジュールを固定する事ができる。（恩恵はおそらく、モジュール指定コマンドでモジュール名を明示的に指定しなくても勝手に固定中のモジュールを割り当てて実行してくれる程度。固定していることを忘れて変なことになるくらいならコマンドごとにモジュール指定したほうがいいかも・・・？）

    ```terminal
    $ php artisan module:use モジュール名
    ```

1. 下記を実行することで固定中のモジュールを解除する事ができる。

    ```terminal
    $ php artisan module:unuse モジュール名
    ```

### モジュールへのパス

- 下記を実行することでモジュールへのパスが取得できるようだ。（筆者はDocker環境なのでコメントのようなパスが返された。tinkerで確認）

    ```php
    $path = module_path('Blog');
    // /var/www/html/Modules/Blog
    ```

### モジュール内でのLaravelMixの実行

- `app/Modules/モジュール`に移動して`$ npm install`などを行えばモジュール固有でLaravelMixを使う事ができるっぽい。
- 詳しくは下記に記載
    - [https://nwidart.com/laravel-modules/v6/basic-usage/compiling-assets](https://nwidart.com/laravel-modules/v6/basic-usage/compiling-assets)

### その他の使い方

- [https://nwidart.com/laravel-modules/v6/advanced-tools/artisan-commands](https://nwidart.com/laravel-modules/v6/advanced-tools/artisan-commands)

# 付録

- `-p`オプション差分

    ```
        Modules/
        ├── Blog
        │   ├── Config
        │   │   └── config.php
        │   ├── Console
        │   ├── Database
        │   │   ├── Migrations
        │   │   ├── Seeders
        │   │   └── factories
        │   ├── Entities
        │   ├── Http
        │   │   ├── Controllers
        │   │   ├── Middleware
        │   │   └── Requests
        │   ├── Providers
        │   │   ├── BlogServiceProvider.php
        │   │   └── RouteServiceProvider.php
        │   ├── Resources
        │   │   ├── assets
        │   │   ├── lang
        │   │   └── views
        │   ├── Routes
        │   │   ├── api.php
        │   │   └── web.php
        │   ├── Tests
        │   │   ├── Feature
        │   │   └── Unit
        │   ├── composer.json
        │   ├── module.json
        │   ├── package.json
        │   └── webpack.mix.js
        └── BlogPlain
            ├── Config
            ├── Console
            ├── Database
            │   ├── Migrations
            │   ├── Seeders
            │   └── factories
            ├── Entities
            ├── Http
            │   ├── Controllers
            │   ├── Middleware
            │   └── Requests
            ├── Providers
            ├── Resources
            │   ├── assets
            │   ├── lang
            │   └── views
            ├── Routes
            ├── Tests
            │   ├── Feature
            │   └── Unit
            └── module.json
    ```

- 各クラス作成コマンド早見表

| 作業 | コマンド | 備考 |
| --- | --- | --- |
| モデル作成 | `$ php artisan module:make-model モデルクラス名 モジュール名` ||
| モデル作成（マイグレーションファイルを添えて） | `$ php artisan module:make-model -m モデルクラス名 モジュール名` ||
| マイグレーション作成 | `$php artisan module:make-migration マイグレーションファイル名 モジュール名 ` ||
| マイグレート | `$ php artisan module:migrate モジュール名` ||
| ロールバック | `$ php artisan module:migrate-rollback モジュール名` ||
| シード作成 | `$ php artisan module:make-seed シードファイル名 モジュール名 ` ||
| シード実行 | `$ php artisan module:seed モジュール名` ||
| コントローラー作成 | `$ php artisan module:make-controller コントローラー名 モジュール名 ` ||
| ミドルウェア作成 | `$ php artisan module:make-middleware ミドルウエア名 モジュール名` ||
| メールクラス作成 | `$ php artisan module:make-mail メールクラス名 モジュール名 ` ||
| Unitテストクラス作成 | `$ php artisan module:make-test テストクラス名 モジュール名` ||

# 参考文献

- [公式ドキュメント](https://nwidart.com/laravel-modules/v6/advanced-tools/artisan-commands)
- [Github](https://github.com/nWidart/laravel-modules)