sebastiaanluca/laravel-module-loader

此包已 弃用 并不再维护。作者建议使用 nwidart/laravel-modules 包。

一个轻量级的包,用于将您的代码拆分为独立的模块。

7.0.0 2021-03-11 13:43 UTC

README

Latest stable release Software license Build status Total downloads

Read my blog View my other packages and projects Follow @sebastiaanluca on Twitter Share this package on Twitter

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 文件。

当然,您也可以手动完成这些操作。在任何模块目录中创建一个 UserUser/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/langYourModule/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

贡献

有关详细信息,请参阅CONTRIBUTINGCODE_OF_CONDUCT

安全

如果您发现任何安全相关的问题,请发送电子邮件至 hello@sebastiaanluca.com,而不是使用问题跟踪器。

致谢

关于

我的名字是Sebastiaan,我是一名专注于构建定制Laravel应用程序的自由职业后端开发者。查看我的作品集以获取更多信息,我的博客提供最新技巧和窍门,以及我的其他以帮助您启动下一个项目。

您有一个需要指导的项目吗?请发送电子邮件至 hello@sebastiaanluca.com