pijler/laravel-modules

Simple package for organizing Laravel projects using modules.

Installs: 1

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/pijler/laravel-modules

v0.1.0 2025-10-11 19:35 UTC

This package is auto-updated.

Last update: 2025-10-11 19:38:40 UTC


README

This package provides a simple yet powerful structure for organizing Laravel applications into independent modules, allowing for a cleaner, more scalable, and maintainable architecture.

Each module is a mini Laravel application with its own routes, views, lang, configs, console, events, policies, and observers, all automatically managed by the ModuleServiceProvider.

📦 Installation

Add the package to your Laravel project:

composer require pijler/laravel-modules

Make sure your composer.json autoload includes the Modules\ namespace:

"autoload": {
  "psr-4": {
    "Modules\\": "modules/"
  }
}

Then run:

composer dump-autoload

🧩 Module Structure

Each module should follow the structure below inside the modules/ directory:

modules/
└── Blog/
    ├── app/
    │   ├── Console/
    │   │   └── Kernel.php
    │   ├── Http/
    │   │   ├── Controllers/
    │   │   └── Middleware/
    │   └── Providers/
    │       ├── AppServiceProvider.php
    │       └── RouteServiceProvider.php
    ├── config/
    │   ├── config.php
    │   └── another.php
    ├── lang/
    │   ├── en-US.json
    │   └── pt_BR.json
    ├── resources/
    │   └── views/
    │       └── index.blade.php
    └── routes/
        └── web.php

⚙️ Module Registration

Each module must contain an AppServiceProvider that extends the base ModuleServiceProvider class.

Example:

<?php

namespace Blog\Providers;

use Modules\ModuleServiceProvider;

class AppServiceProvider extends ModuleServiceProvider
{
    /**
     * The module slug.
     */
    protected string $slug = 'blog';

    /**
     * The module name.
     */
    protected string $module = 'Blog';

    /**
     * Boot the gates for the module.
     */
    protected function bootGates(): void
    {
        //
    }

    /**
     * Boot the events for the module.
     */
    protected function bootEvents(): void
    {
        //
    }

    /**
     * Boot the policies for the module.
     */
    protected function bootPolicies(): void
    {
        //
    }

    /**
     * Boot the observers for the module.
     */
    protected function bootObservers(): void
    {
        //
    }
}

Then, register the provider in bootstrap/providers.php:

return [
    /*
     * Modules Service Providers...
     */
    Blog\Providers\AppServiceProvider::class,
];

Add a namespace mapping for the module in your composer.json:

"autoload": {
  "psr-4": {
    "Blog\\": "modules/Blog/app/"
  }
}

🧠 Internal Functionality

The base ModuleServiceProvider automatically handles the booting of all module resources.

✅ Views

Automatically loads views from:

resources/views

And makes them available under the module namespace ($slug):

@include('blog::index')

✅ Translations

Supports both JSON and PHP translation files.

Automatically loads from:

lang/

Usage examples:

trans('Hello world'); // JSON
trans('blog::messages.welcome'); // PHP

✅ Configuration

Automatically loads and merges:

  • A single config.php file
  • Or multiple files inside the config/ directory

They can be accessed via config("{$slug}.key").

✅ Commands & Schedule

If a app/Console/Kernel.php exists within the module, the provider:

  • Registers Artisan commands located in the /Commands directory.
  • Registers scheduled tasks defined in the schedule(Schedule $schedule) method.

Example:

namespace Blog\Console;

use Illuminate\Console\Scheduling\Schedule;
use Modules\BaseKernel;

class Kernel extends BaseKernel
{
    /**
     * Define the application's command schedule.
     */
    public function schedule(Schedule $schedule): void
    {
        $schedule->command('blog:clean-posts')->daily();
    }

    /**
     * Register the commands for the application.
     */
    public function commands(): array
    {
        return $this->load(__DIR__.'/Commands');
    }
}

✅ Dynamic Booting

The provider automatically attempts to execute the following methods, if they exist:

  • bootGates()
  • bootEvents()
  • bootPolicies()
  • bootObservers()

This allows additional resources to be registered without overriding boot().

🔍 Helpers

module_has(string $module): bool

Checks if a module exists inside the modules/ directory.

Parameters
Name Type Description
$module string The name of the module to check.
Return
Type Description
bool true if the module exists, false otherwise.
Example
if (module_has('Users')) {
    // The "Users" module exists
}

module_path(string $module, string $path = ''): string

Returns the full path to a module directory inside modules/.

Parameters
Name Type Description
$module string The name of the module.
$path string Additional path within the module (optional).
Return
Type Description
string The absolute path to the module directory.
Example
$path = module_path('Users');
// Returns something like: /var/www/app/modules/Users

$configPath = module_path('Users', 'config/module.php');
// Returns: /var/www/app/modules/Users/config/module.php

🧩 Benefits

✅ Modular and independent organization
✅ Automatic loading of configs, views, and translations
✅ Native integration with Scheduler and Artisan
✅ Dynamic boot for gates, policies, observers, and events
✅ Fully compatible with the Laravel ecosystem

📝 License

Open-source under the MIT license.

🚀 Thanks!