Installation:
composer require hexters/laramodule
Publish the package configuration and migrations:
php artisan vendor:publish --provider="Hexters\Laramodule\LaramoduleServiceProvider" --tag="config"
php artisan vendor:publish --provider="Hexters\Laramodule\LaramoduleServiceProvider" --tag="migrations"
php artisan migrate
First Module Creation: Generate a new module with:
php artisan module:make Blog
This creates a Modules/Blog directory with default structure (controllers, routes, views, etc.).
Registering a Module:
Add the module to config/laramodule.php under the modules array:
'modules' => [
'Blog' => [
'enabled' => true,
'path' => base_path('Modules/Blog'),
],
],
First Use Case:
Define a route in Modules/Blog/Routes/web.php:
Route::get('/posts', 'BlogController@index');
Access it via /blog/posts (or your configured module prefix).
Modular Routing:
Route::module('Blog') prefix in module-specific route files to auto-prefix routes with the module name.Route::module('Blog')->get('/posts', 'BlogController@index');
Modules/{Module}/Routes/web.php and Modules/{Module}/Routes/api.php.Service Providers:
Modules/{Module}/Providers/{Module}ServiceProvider.php).boot() method:
public function boot()
{
$this->app->bind('BlogService', function () {
return new BlogService();
});
}
Views & Assets:
Modules/{Module}/Resources/views.@include('modules::{Module}::partials.header') to reference module-specific views.php artisan module:publish-assets Blog
Database & Migrations:
Modules/{Module}/Database/Migrations.php artisan module:migrate Blog
Modules/{Module}/Database/Seeders).Dependency Injection:
public function __construct(BlogService $blogService) {
$this->blogService = $blogService;
}
Module Activation/Deactivation:
laramodule:enable/laramodule:disable commands:
php artisan laramodule:enable Blog
php artisan laramodule:disable Blog
config/laramodule.php or via the Module facade:
if (Module::isEnabled('Blog')) { ... }
Middleware:
Modules/{Module}/Http/Kernel.php:
protected $middleware = [
\App\Http\Middleware\VerifyBlogAuth::class,
];
Events & Listeners:
event(new \Modules\Blog\Events\PostCreated($post));
Route Prefix Conflicts:
/blog/posts) don’t clash with global routes.Route::module('Blog')->prefix('custom-prefix') to override defaults.Namespace Collisions:
Modules\Blog\Http\Controllers\BlogController).Caching Issues:
php artisan cache:clear
php artisan config:clear
php artisan route:clear
Service Provider Loading Order:
config/app.php if dependencies exist between modules.View Path Resolution:
views path in Modules/{Module}/composer.json:
"extra": {
"laravel": {
"views": "Resources/views"
}
}
Database Transactions:
php artisan module:migrate Blog --seed to run migrations + seeders together.Testing Modules:
$this->app->instance(\Modules\Blog\Services\BlogService::class, MockBlogService::class);
Check Module Status:
php artisan laramodule:list
Lists all modules and their enabled/disabled status.
Route Debugging:
Use php artisan route:list to verify module routes are registered. Filter by module:
php artisan route:list | grep blog
Service Binding Issues:
config/app.php under providers.php artisan package:discover to refresh service providers.View Debugging:
APP_DEBUG=true in .env) to catch missing view errors.php artisan view:clear
Custom Module Commands:
Extend the package by creating custom commands in app/Console/Commands and binding them to the module’s service provider.
Module Events:
Listen for module lifecycle events (e.g., ModuleEnabled, ModuleDisabled) in your app’s event listeners.
Dynamic Module Loading:
Use the Module facade to dynamically load module configurations:
$moduleConfig = Module::config('Blog');
API for Module Management:
Build an admin panel to manage modules via the Hexters\Laramodule\Contracts\ModuleRepository interface.
Override Default Behaviors:
Bind interfaces in your app’s service provider to replace default implementations (e.g., ModuleRepository).
How can I help you explore Laravel packages today?