Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Modular Laravel Package

internachi/modular

A lightweight module system for Laravel apps using Composer path repositories and Laravel package discovery. Create self-contained modules in an app-modules/ directory, following standard Laravel package conventions with minimal extra tooling.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation

    composer require internachi/modular
    
    • No manual configuration required; Laravel auto-discovers the package.
  2. Publish Config (Optional but Recommended)

    php artisan vendor:publish --tag=modular-config
    
    • Customize the default module namespace (e.g., InterNACHI\) in config/app-modules.php.
  3. Create Your First Module

    php artisan make:module my-module
    
    • This scaffolds a module in app-modules/my-module/ with standard Laravel conventions.
    • Update composer.json and run:
      composer update modules/my-module
      
  4. Sync Project Configs (Optional)

    php artisan modules:sync
    
    • Updates phpunit.xml and PhpStorm configs to recognize modules.

First Use Case: Creating a Module-Specific Model

php artisan make:model User --module=my-module
  • Generates a model in app-modules/my-module/src/Models/User.php.
  • Automatically registers migrations, factories, and policies under the module namespace.

Implementation Patterns

1. Modular Development Workflow

  • Directory Structure:

    app-modules/
      ├── my-module/
      │   ├── src/          # Core logic (Models, Services, etc.)
      │   ├── resources/    # Views, Lang, Assets
      │   ├── routes/       # Module-specific routes
      │   ├── database/    # Migrations, Seeders, Factories
      │   └── tests/        # Module tests
    
  • Key Conventions:

    • Namespaces: Use Modules\MyModule\ (or your custom namespace) for all module classes.
    • Autoloading: Modules are treated as Composer path repositories. No manual use statements needed for cross-module imports.
    • Service Providers: Register providers in src/Providers/ (auto-discovered by Laravel).

2. Leveraging Laravel’s make: Commands

  • Module-Specific Artisan Commands:

    php artisan make:controller AdminController --module=my-module
    php artisan make:policy UserPolicy --module=my-module
    php artisan make:job ProcessPayment --module=my-module
    
    • All generated files are placed in the correct module directory with proper namespaces.
  • Database Operations:

    php artisan make:migration create_users_table --module=my-module
    php artisan db:seed --module=my-module  # Runs `Modules\MyModule\Database\Seeders\DatabaseSeeder`
    

3. Blade Components and Views

  • Component Auto-Discovery:

    • Files in resources/components/ or src/View/Components/ are auto-registered.
    • Use namespaced components in Blade:
      <x-my-module::component-name />
      <x-my-module::nested.component />
      
  • Views:

    • Store views in resources/views/ (module-specific paths are auto-resolved).
    • Example: app-modules/my-module/resources/views/dashboard.blade.php@include('my-module::dashboard').

4. Translations

  • Language Files:
    • Place files in resources/lang/{locale}/.
    • Access translations with:
      __('my-module::messages.welcome');
      

5. Routing

  • Module-Specific Routes:
    • Define routes in routes/web.php (module directory) or routes/api.php.
    • Prefix routes with the module name for clarity:
      Route::prefix('my-module')->group(function () {
          Route::get('/dashboard', [DashboardController::class, 'index']);
      });
      

6. Testing

  • Test Structure:
    • Tests in tests/ are auto-discovered.
    • Use Modules\Tests\TestCase as the base class for module tests.
    • Run module-specific tests:
      php artisan test --module=my-module
      

7. Service Providers and Bootstrapping

  • Register Providers:

    • Create a provider in src/Providers/ (e.g., MyModuleServiceProvider).
    • Extend Illuminate\Support\ServiceProvider and bind module-specific services.
    • The provider is auto-loaded by Laravel’s package discovery.
  • Bootstrapping:

    • Use the boot() method to register module-specific bindings or listeners:
      public function boot()
      {
          $this->app->bind('my-module.service', function () {
              return new MyModuleService();
          });
      }
      

8. Cross-Module Dependencies

  • Importing Classes:

    • Use fully qualified namespaces (no need for use statements in Blade or config files):
      use Modules\MyModule\Models\User;
      
    • Composer’s path repositories handle autoloading.
  • Shared Services:

    • Register shared services in a module’s provider and bind them to the container.

Gotchas and Tips

Pitfalls

  1. Namespace Conflicts:

    • Ensure module namespaces (e.g., Modules\MyModule\) don’t clash with existing app namespaces.
    • Fix: Use a unique root namespace (e.g., App\Modules\) via config/app-modules.php.
  2. Composer Path Repository Issues:

    • If composer update modules/my-module fails, manually add the path repository to composer.json:
      "repositories": [
          {
              "type": "path",
              "url": "app-modules/*"
          }
      ]
      
    • Tip: Run composer dump-autoload after manual changes.
  3. Windows Path Normalization:

    • Module paths may not resolve correctly on Windows. Use forward slashes (app-modules/my-module) or configure Composer’s config.platform.check:
      composer config platform.check false
      
  4. PhpStorm IDE Issues:

    • After creating a module, run php artisan modules:sync to update PhpStorm’s library roots.
    • Manual Fix: Add app-modules/* to PhpStorm’s Settings > Languages & Frameworks > PHP > Include Path.
  5. Livewire/Laravel Livewire:

    • The --module flag for make:livewire only works if Livewire is installed. Install it first:
      composer require livewire/livewire
      
  6. Migration Conflicts:

    • If migrations fail due to table name collisions, prefix tables with the module name:
      Schema::create('my_module_users', function (Blueprint $table) { ... });
      
  7. Event Listeners:

    • Ensure listeners in src/Listeners/ are registered in the module’s provider or use the EventServiceProvider.

Debugging Tips

  1. Check Module Loading:

    • List loaded modules to verify auto-discovery:
      php artisan modules:list
      
    • Clear the module cache if modules aren’t loading:
      php artisan modules:clear
      
  2. Composer Autoload:

    • Regenerate autoload files after adding new modules:
      composer dump-autoload
      
  3. Route Debugging:

    • Dump routes to check if module routes are registered:
      php artisan route:list
      
  4. Blade Component Debugging:

    • Verify component namespaces in resources/views/vendor/composer.json (auto-generated by Laravel).
  5. Translation Debugging:

    • Check if language files are loaded:
      dd(app('translator')->getLoader()->getNamespaces());
      

Extension Points

  1. Custom Module Stubs:

    • Publish and override stubs for make:module:
      php artisan vendor:publish --tag=modular-stubs
      
    • Edit stubs in resources/stubs/module/.
  2. Dynamic Module Loading:

    • Disable auto-discovery for specific modules by excluding them in config/app-modules.php:
      'exclude' => [
          'disabled-module',
      ],
      
  3. Module-Specific Config:

    • Use Laravel’s config system to share settings across modules:
      config(['my-module.setting' => 'value']);
      
    • Access in modules:
      config('my-module.setting');
      
  4. Testing Modules in Isolation:

    • Use Laravel’s --env=testing flag and mock dependencies:
      php artisan test --env=testing --module=my-module
      
  5. Extracting Modules to Packages:

    • To convert a module to a standalone package:
      1. Move the module to vendor/ (e.g., vendor/my-module/).
      2. Update composer.json to require the package.
      3. Adjust namespaces to match the package (e.g., MyModule\).

Pro Tips

  1. **Use --module
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport
twbs/bootstrap4