モジュール性を実現するための Laravel のハッキング
プロジェクトが成長するにつれて、そのモノリシックな
典型的なアプローチは、Laravel フォルダー構造を多くのフォルダーに複製することです.例えば
しかし、小さな問題があります.私たちが大好きな 😍
恐れるな、我が友よ!今日は、この問題を解決し、
そして、コードをコピーして ⚡⚡⚡ 周りに貼り付けるわずか 5 分でそれに取り組みます 準備はできましたか?
次のようなことができるようにしたいと考えています.
しかし、
また、56 行目に小さな変更を加える必要があります.
Laravel はモジュールとパッケージを処理するように作られていますが、それらを発見する方法を Laravel に伝える必要があります.そのためには、サービス プロバイダーが必要になります.
次のように入力します.
モジュールのフォルダー構造が必要です (または、モデル クラスが
また、
後で作成する各モジュールの最後の 3 行をコピーして貼り付けます.
これで、モデルとそれに関連するクラスを作成できます.
結果?
一部の make コマンドは、使用している
それでおしまい.
また、tinker を使用して請求書を生成しようとすると、次のようになります.
私たちのデータベースではすべてがうまく機能しているようです👌
まあ、それはほとんどそれです.利用可能なすべてのバニラ
モジュールにビュー、ルート、イベントなどが必要な場合は、
この記事を読んで楽しんでいただければ幸いです.もしそうなら、❤️ または 🦄 を残してください.PHP、アーキテクチャ、Laravel に関する記事を毎月書いています.
免責事項 今朝シャワーを浴びているときにこのアイデアを思いつきました🚿 これの影響を完全にテストしていないので、この方法を適用する際には注意することをお勧めします.気づいたことをコメントで教えてください👍
app/
フォルダーをモジュールと呼ばれる小さなチャンクに分割することが有利になります.ご存知のように、構造化されたものを維持するために 😜典型的なアプローチは、Laravel フォルダー構造を多くのフォルダーに複製することです.例えば
modules/
billing/
app/ database/ routes/
shop/
app/ database/ routes/
blog/
app/ database/ routes/
しかし、小さな問題があります.私たちが大好きな 😍
make:something
コマンドは、目覚ましい生産性のために毎日頼っていますが、この構造では機能しません 🙁恐れるな、我が友よ!今日は、この問題を解決し、
make:*
コマンドをモジュラー フォルダー構造でうまく機能させる方法を紹介します.そして、コードをコピーして ⚡⚡⚡ 周りに貼り付けるわずか 5 分でそれに取り組みます 準備はできましたか?
すべての Artisan コマンドの新しいオプション
次のようなことができるようにしたいと考えています.
php artisan make:model --module billing --all Invoice
しかし、
*MakeCommand
個のクラスをすべて書き直したいわけではありません. 💉 このスニペットを artisan
ファイル内に直接挿入します.require __DIR__.'/vendor/autoload.php';
$app = require_once __DIR__.'/bootstrap/app.php'; // <--- be sure to paste AFTER this line
/*
|--------------------------------------------------------------------------
| Detect The Module Context
|--------------------------------------------------------------------------
|
| If you wish to run a given command (usually a make:something) in the
| context of a module, you may pass --module <name> as arguments. The
| following snippet will swap the base directory with the module directory
| and erase the module arguments so the command can run normally.
|
*/
if ((false !== $offset = array_search('--module', $argv)) && !empty($argv[$offset + 1])) {
$modulePath = $app->basePath("modules/{$argv[$offset + 1]}");
$app->useAppPath("{$modulePath}/app");
$app->useDatabasePath("{$modulePath}/database");
unset($argv[$offset], $argv[$offset + 1]);
}
また、56 行目に小さな変更を加える必要があります.
$status = $kernel->handle(
$input = new Symfony\Component\Console\Input\ArgvInput($argv), // <---- add ($argv) here!
new Symfony\Component\Console\Output\ConsoleOutput
);
新しいサービス プロバイダーの紹介
Laravel はモジュールとパッケージを処理するように作られていますが、それらを発見する方法を Laravel に伝える必要があります.そのためには、サービス プロバイダーが必要になります.
php artisan make:provider ModuleServiceProvider
次のように入力します.
namespace App\Providers;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Str;
class ModuleServiceProvider extends ServiceProvider
{
/**
* Register services.
*
* @return void
*/
public function register()
{
/** Fixing Factory::resolveFactoryName */
Factory::guessFactoryNamesUsing(function (string $modelName) {
$namespace = Str::contains($modelName, "Models\\")
? Str::before($modelName, "App\\Models\\")
: Str::before($modelName, "App\\");
$modelName = Str::contains($modelName, "Models\\")
? Str::after($modelName, "App\\Models\\")
: Str::after($modelName, "App\\");
return $namespace . "Database\\Factories\\" . $modelName . "Factory";
});
}
/**
* Bootstrap services.
*
* @return void
*/
public function boot()
{
foreach (glob(base_path('modules/*')) ?: [] as $dir) {
$this->loadMigrationsFrom("{$dir}/database/migrations");
$this->loadTranslationsFrom("{$dir}/resources/lang", basename($dir));
$this->loadViewsFrom("{$dir}/resources/views", basename($dir));
}
}
}
config/app.php
に登録します./*
* Application Service Providers...
*/
App\Providers\AppServiceProvider::class,
App\Providers\ModuleServiceProvider::class, // <--- here it is!
App\Providers\AuthServiceProvider::class,
// App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
最初のモジュールを作ってみましょう
モジュールのフォルダー構造が必要です (または、モデル クラスが
modules/name/app/
のルートに生成されます).mkdir -p modules/billing/app/Models
また、
composer.json
も更新する必要があります.{
"autoload": {
"psr-4": {
"App\\": "app/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/",
"Modules\\Billing\\App\\": "modules/billing/app",
"Modules\\Billing\\Database\\Factories\\": "modules/billing/database/factories/",
"Modules\\Billing\\Database\\Seeders\\": "modules/billing/database/seeders/"
}
}
}
後で作成する各モジュールの最後の 3 行をコピーして貼り付けます.
これで、モデルとそれに関連するクラスを作成できます.
php artisan make:model --module billing --all Invoice
結果?
billing/app/
Http/Controllers/OrderController.php
Models/Order.php
Policies/OrderPolicy.php
billing/database/
factories/OrderFactory.php
migrations/2021_09_21_203852_create_orders_table.php
seeders/OrderSeeder.php
いくつかのものを修正する
一部の make コマンドは、使用している
base_path()
に関係なく、正しい名前空間を生成しません (シーダー スタブの場合、ハードコードされています 🤦).彼らは単にこのように動作することを意図していませんでした.それでは、それを修正しましょう.modules/billing/database/factories/InvoiceFactory.php
で:namespace Modules\Billing\Database\Factories; // <--- add the Modules\Billing prefix
modules/billing/database/seeders/InvoiceSeeder.php
でまったく同じことを行います.それでおしまい.
php artisan migrate
を実行すると、次のように表示されます.Migrating: 2021_09_21_203852_create_invoices_table
Migrated: 2021_09_21_203852_create_invoices_table (38.79ms)
また、tinker を使用して請求書を生成しようとすると、次のようになります.
Psy Shell v0.10.8 (PHP 8.0.9 — cli) by Justin Hileman
>>> Modules\Billing\App\Models\Invoice::factory()->create()
=> Modules\Billing\App\Models\Invoice {#3518
updated_at: "2021-09-21 21:32:15",
created_at: "2021-09-21 21:32:15",
id: 1,
}
私たちのデータベースではすべてがうまく機能しているようです👌
おめでとうございます。
まあ、それはほとんどそれです.利用可能なすべてのバニラ
make:*
コマンドをテストしましたが、それらのほとんどは正常に動作します (もちろん、修正しなければならなかったデータベースのものを除きます).モジュールにビュー、ルート、イベントなどが必要な場合は、
make:provider
コマンドを乱用することをお勧めします.php artisan make:provider --module billing RouteServiceProvider
読んでくれてありがとう
この記事を読んで楽しんでいただければ幸いです.もしそうなら、❤️ または 🦄 を残してください.PHP、アーキテクチャ、Laravel に関する記事を毎月書いています.
免責事項 今朝シャワーを浴びているときにこのアイデアを思いつきました🚿 これの影響を完全にテストしていないので、この方法を適用する際には注意することをお勧めします.気づいたことをコメントで教えてください👍
Reference
この問題について(モジュール性を実現するための Laravel のハッキング), 我々は、より多くの情報をここで見つけました https://dev.to/bdelespierre/very-very-simple-laravel-modules-4927テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol