sebastiaanluca / laravel-module-loader
Requires
- php: ^8.0
- laravel/framework: ^8.0
Requires (Dev)
- mockery/mockery: ^1.3.4
- orchestra/testbench: ^6.4
- phpunit/phpunit: ^9.5
README
Laravel Module Loader 可以帮助您通过将域代码拆分为上下文模块来组织项目。
默认情况下,Laravel 为您提供了一个 app/
目录来放置所有类。在中型到大型项目中,您通常会得到一个庞大的 app/
目录,包含成百上千的目录和类。为了使其中的一些有“意义”,它们通常按 类类型(例如,提供者、服务、模型等)组织。
一种替代方法 是将代码组织在同一上下文中的组,即模块。由于您通常一次开发一个功能,因此当在这个上下文中工作时,这使您和其他开发人员更容易找到相关代码。
此外,这个轻量级模块包在利用 include 模块服务提供者时提供了一些额外的优势,包括
- 单独的配置;
- 可发布的配置;
- 迁移;
- 种子;
- Eloquent 工厂;
- (PHP 数组或 JSON)翻译;
- 视图;
- Eloquent 多态映射支持;
- 自动事件监听器或订阅者注册;
- 以及自动 路由映射。
示例
为了给您一个模块化项目的结构感,以用户、文档和购物车模块为例
User/
database/
factories/
migrations/
seeds/
resources/
lang/
views/
src/
Commands/
Jobs/
Models/
Providers/
UserServiceProvider
tests/
UserTestCase
Document/
resources/
lang/
src/
Models/
Providers/
DocumentServiceProvider
ShoppingCart/
src/
Providers/
ShoppingCartServiceProvider
目录
要求
- PHP 8 或更高版本
- Laravel 8 或更高版本
如何安装
通过 Composer
composer require sebastiaanluca/laravel-module-loader
入门
入门只需一个步骤,那就是 创建一个模块。
创建模块
假设您想要创建一个模块来组织所有与 用户 相关的类和文件,运行
php artisan modules:create User
然后包会
- 在您的配置主模块目录下生成用户模块目录;
- 生成一个正确命名的(可选)服务提供商,以充分利用此包的功能;
- 并将其自动加载信息写入您的 composer.json 文件。
当然,您也可以手动完成这些操作。在任何模块目录中创建一个 User
和 User/src
目录,然后运行 php artisan modules:refresh
以将其添加到 composer.json 文件中(或者也可以手动操作)。
生产环境中的缓存
可选
为了减少在应用程序启动期间读取的文件数量,您可以选择缓存您的模块服务提供商列表以改善加载时间。除了 Composer 提供的所有模块类的缓存列表外,该包在启动时仅读取一个缓存文件,并注册这些文件而不是扫描所有模块目录并在运行时加载它们。特别适用于生产环境,建议在项目部署期间运行。
要缓存所有提供商,运行
php artisan modules:cache
要清除缓存文件,执行
php artisan modules:clear
深入了解
扫描和注册模块
当您手动创建了一个新模块,进行了一些更改,添加了需要自动加载的目录等,您应该刷新您的模块
php artisan modules:refresh
这将扫描所有模块目录的更改,将模块的自动加载配置写入 composer.json(当适用时包括 classmap、PSR-4 和 PSR-4 开发部分),并自动更新 Composer 自动加载器。
除非以下情况,否则您的现有 Composer 配置不会被更改,也不会更改自动加载条目;
- 模块丢失;
- 存在重复模块(其中一个条目将被保留)。
如果您希望保留所有 不存在模块 的自动加载条目,您可以使用 --keep
选项
php artisan modules:refresh --keep
使用模块服务提供商
可选
如果您想让模块支持
- 单独的配置;
- 可发布的配置;
- 迁移;
- 种子;
- Eloquent 工厂;
- (PHP 数组或 JSON)翻译;
- 视图;
- Eloquent 多态映射支持;
- 自动事件监听器或订阅者注册;
- 以及自动 路由映射。
当您创建一个模块时,会为您生成一个服务提供商。如果您想自己创建一个提供商并在框架启动时自动注册,请在模块的 src/Providers
目录中创建一个扩展正确基础提供商的类。
请特别注意您提供商的 大写命名,因为它只有在类名以您的模块名称开头时才会注册。
<?php declare(strict_types=1); namespace MyModule\Providers; use SebastiaanLuca\Module\Providers\ModuleProvider; class MyModuleServiceProvider extends ModuleProvider { /** * Register the application services. * * @return void */ public function register() : void { parent::register(); } /** * Bootstrap the application services. * * @return void */ public function boot() : void { parent::boot(); } }
单个模块配置
可选;需要 模块服务提供商
每个模块都可以包含一个配置文件,您可以使用它来分组相关设置。配置文件的命名和位置(蛇形命名)对于您想要自动加载它很重要。以一个 ShoppingCart
模块为例
modules/
ShoppingCart/
config/
shopping-cart.php
database/
src/
文件的内容类似于任何其他 Laravel 配置文件,可以包含您想要的任何内容
<?php return [ 'setting' => 'value', ];
要检索一个设置,可以这样调用它
$setting = config('shopping-cart.setting') // "value"
发布模块配置
可选;需要 模块服务提供商
如果您不想配置位于模块本身,您可以选择将其复制或移动到根目录的 /config
目录。另一种选择是像发布包配置文件一样发布它,即让 Laravel 帮您复制它。
php artisan vendor:publish
然后在列表中选择 * 您的模块(配置)
。
请注意,这两个配置文件都将合并,但根目录 /config
中的文件将优先于模块中的文件。如果在两个文件中遇到相同的键,则将忽略模块中的键。
使用迁移
可选;需要 模块服务提供商
Laravel 模块加载器在组织迁移方面提供了两种选项。要么您将它们保留在默认的 /database/migrations
目录中,以维护所有迁移的时间顺序概述,要么您根据模块在例如 YourModule/database/migrations
中上下文存储。
这两个位置都很好,可以互换;即,您可以根据它们的日期和时间前缀将它们组合起来排序和执行。
使用工厂
可选;需要 模块服务提供商
工厂可以存储在您的默认 /database/factories
目录中,或者在例如 YourModule/database/factories
中按模块存储。默认情况下,它们不是命名空间化的,并且仅在 开发环境中 加载,以防止您的应用程序在 autoload-dev 包(如 Faker)未安装在生产系统上时抛出错误。
使用种子文件
可选;需要 模块服务提供商
种子文件可以放在您的默认 /database/seeds
目录中,或者在 YourModule/database/seeds
中按模块放置。它们不是命名空间化的,并且全局可用,因此请注意跨模块具有相同名称的种子文件。
使用翻译
可选;需要 模块服务提供商
翻译保存在 /resources/lang
或 YourModule/resources/lang
模块目录中。如果您使用后者并在模块中保留它们,请记住使用 snake case 模块名称(就像您正在使用一个包一样)作为翻译键的前缀以检索正确的值。
@lang('your-module::dashboard.intro') @lang('your-module::auth/password_reset.label')
使用视图
可选;需要 模块服务提供商
与翻译类似,视图遵循相同的模式。您可以将它们保留在默认的 /resources/views
目录中或在 YourModule/resources/views
中。要使用视图或包含部分,请使用您的 snake case 模块名称作为路径的前缀。
view('my-module::dashboard') @include('my-module::pages.auth.password_reset') @include('my-module::pages/welcome')
简化多态模型类型映射
可选;需要 模块服务提供商
您不需要手动调用 Relation::morphMap([])
,而是可以通过在模块服务提供者中定义一个形态映射数组来映射 Eloquent 模型的多态类型或别名。
<?php declare(strict_types=1); namespace MyModule\Providers; use MyModule\Models\Item; use MyModule\Models\ShoppingCart; use SebastiaanLuca\Module\Providers\ModuleProvider; class MyModuleServiceProvider extends ModuleProvider { /** * The polymorphic models to map to their alias. * * @var array */ protected $morphMap = [ 'item' => Item::class, 'shopping_cart' => ShoppingCart::class, ]; }
务必查看我的其他 自动形态映射 包,以 自动将所有模型别化 而无需编写任何代码。
简化事件监听器注册
可选;需要 模块服务提供商
同样,您可以在模块服务提供者中定义形态映射,也可以定义事件监听器或订阅者列表。
<?php declare(strict_types=1); namespace MyModule\Providers; use MyModule\Listeners\UpdateUserInfo; use MyModule\Listeners\UserEventSubscriber; use SebastiaanLuca\Module\Providers\ModuleProvider; use Users\Events\UserCreated; class MyModuleServiceProvider extends ModuleProvider { /** * The event listener mappings for the application. * * @var array */ protected $listen = [ UserCreated::class => [ UpdateUserInfo::class, ] ]; /** * The subscriber classes to register. * * @var array */ protected $subscribe = [ UserEventSubscriber::class, ]; }
自动路由映射
可选;需要 模块服务提供商
在中型或大型 Laravel 应用程序中处理和组织路由可能会很快变得混乱。为了应对不断增长的路线列表,此包提供了对 sebastiaanluca/laravel-router 的支持,以自动注册和映射您的上下文路由和路由器。
<?php declare(strict_types=1); namespace MyModule\Providers; use MyModule\Http\Routers\UserAuthRouter; use MyModule\Http\Routers\UserDashboardRouter; use SebastiaanLuca\Module\Providers\ModuleProvider; class MyModuleServiceProvider extends ModuleProvider { /** * The routers to be automatically mapped. * * @var array */ protected $routers = [ UserAuthRouter::class, UserDashboardRouter::class, ]; }
自动服务提供者注册
可选;需要 模块服务提供商
为了防止模块的服务提供者在代码行数和方法数量上失控,最好将其拆分为多个其他服务提供者,每个提供者执行单个任务。例如,可以使用ModuleEventProvider
来映射模块的所有事件,而另一个ModuleRouteProvider
可以包含所有路由或路由器,以便在应用程序启动时轻松映射。
当然,这些提供者仍然需要注册。您可以在模块的默认提供者中手动完成此操作,也可以使用列表自动完成。
<?php declare(strict_types=1); namespace MyModule\Providers; use MyModule\Providers\ModuleEventProvider; use MyModule\Providers\ModuleRouteProvider; use SebastiaanLuca\Module\Providers\ModuleProvider; class MyModuleServiceProvider extends ModuleProvider { /** * The additional providers to register. * * @var array */ protected $providers = [ ModuleEventProvider::class, ModuleRouteProvider::class, ]; }
包配置
要将包的配置文件复制到您的根配置目录,请运行以下命令:
php artisan vendor:publish
然后从列表中选择laravel-module-loader (配置)
。
运行时自动加载
此包支持运行时自动加载所有模块及其非命名空间数据库目录。基本上,它会在框架启动期间读取和加载您的模块,而不是像以前那样依赖Composer来在加载模块的类之前自动加载。
将包的配置中的runtime_autoloading
设置为true
,并从composer.json的自动加载部分中删除模块条目。
请注意,启用此功能有一些权衡
- 您不能使用
composer dumpautoload -a
生成权威的类映射(通常在生产环境中); - 它稍微慢一些(但几乎不明显),但您不需要保持composer.json更新;
- PHPStorm(以及其他IDE)不会自动将模块及其测试标记为命名空间源。
模块目录
默认情况下,只有根项目中modules
目录被扫描为模块。通过更改或扩展此列表,您可以进一步组织模块所在的目录或目录。
例如,您可以将个人和工作相关的模块分组到各自的文件夹中,以便在项目中重用。
开发环境
开发环境配置选项允许您更改环境列表...
- 应该加载工厂;
- 并且测试将自动加载(如果启用了运行时自动加载)。
应用程序环境通过Laravel应用程序配置从您的.env
文件中读取。
许可证
此包在MIT许可证(MIT)下运行。有关更多信息,请参阅LICENSE。
变更日志
有关最近更改的更多信息,请参阅CHANGELOG。
测试
composer install
composer test
贡献
有关详细信息,请参阅CONTRIBUTING和CODE_OF_CONDUCT。
安全
如果您发现任何安全相关的问题,请发送电子邮件至 hello@sebastiaanluca.com,而不是使用问题跟踪器。
致谢
关于
我的名字是Sebastiaan,我是一名专注于构建定制Laravel应用程序的自由职业后端开发者。查看我的作品集以获取更多信息,我的博客提供最新技巧和窍门,以及我的其他包以帮助您启动下一个项目。
您有一个需要指导的项目吗?请发送电子邮件至 hello@sebastiaanluca.com!