Weave 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

Module Bundle Laravel Package

pablodip/module-bundle

Symfony bundle that adds a lightweight module system for organizing application code into self-contained, reusable modules with their own controllers, templates, routing, and configuration.

View on GitHub
Deep Wiki
Context7

Getting Started

Read this first: it is not a Laravel package. pablodip/module-bundle is a Symfony2-era bundle. There is no service provider, no extra.laravel package-discovery block, no Illuminate\* dependency, and no code that touches Laravel's container, router, or event loop. Composer will happily install it next to Laravel, but nothing in Laravel will boot it. So "getting started" splits into two tracks: the native track (if you are maintaining a legacy Symfony2 app) and the Laravel track (which is a reimplementation of the idea, not an integration).

Native track — where to look, in order:

  1. The repo's composer.json — this pins the Symfony version and the autoload era (likely PSR-0). Do this before anything else; it decides whether the rest is even runnable.
  2. PablodipModuleBundle.php — the bundle class; tells you what it registers and on what hook.
  3. DependencyInjection/ — the extension's load() method and any Configuration class. This is the real documentation: it tells you the config schema, defaults, and which services get wired.
  4. Any routing loader / route-loader class — this is where the module directory conventions live. This is the part worth understanding, because it is the actual idea being sold.
  5. README last. It is thinner than the DI extension.

Minimal first use case (native): register new Pablodip\ModuleBundle\PablodipModuleBundle() in AppKernel.php, import the bundle's route loader once in app/config/routing.yml, create one module directory containing a single controller action, one template, and one route, clear app/cache/*, then hit the URL. app/console debug:router is the fastest way to confirm the convention your module layout is actually expected to follow.

Laravel track — first use case: do not install it. Your first use case is a single app/Modules/Billing/ folder containing a controller, a routes.php, a Providers/BillingServiceProvider.php, and a resources/views/ directory, registered from config/app.php (or via discovery from composer.json). That is the same unit of organization the bundle provides, expressed in the framework you actually run. If you want the batteries-included version, evaluate nwidart/laravel-modules instead.

Implementation Patterns

The honest day-to-day pattern for a Laravel developer is pattern translation, not package usage. Take each concept the bundle implements in Symfony2 and map it to its Laravel counterpart:

Bundle concept (Symfony2) Laravel equivalent
Bundle registration in AppKernel Service provider in config/app.php or extra.laravel.providers discovery
DI extension load() + Configuration schema register() / boot() plus mergeConfigFrom()
Route loader discovering module routes loadRoutesFrom(__DIR__.'/routes.php') in boot()
Resources/views resolving per module loadViewsFrom(__DIR__.'/resources/views', 'billing')
Per-module service YAML Container bindings inside register()
Module folder = feature slice app/Modules/{Name}/ with a provider per module

Feature-slice discipline. The bundle's one durable idea: a module owns its controllers, routes, templates, config, and services, and nothing else needs to know about it. Enforce that in Laravel by making each module provider the only registration point for its piece of the app. When a controller needs a service, resolve it through the module's binding — do not reach into app/Services. Portability is the whole point; a module that only depends on the container and framework contracts can be lifted into another app or turned into a standalone package later.

Per-module service providers as the composition root. Keep each provider small and explicit:

class BillingServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->mergeConfigFrom(__DIR__.'/config/billing.php', 'billing');
        $this->app->bind(BillingGateway::class, StripeGateway::class);
    }

    public function boot(): void
    {
        $this->loadRoutesFrom(__DIR__.'/routes.php');
        $this->loadViewsFrom(__DIR__.'/resources/views', 'billing');
        $this->loadMigrationsFrom(__DIR__.'/database/migrations');
    }
}

Convention-driven routing. The bundle's core value is that routes are discovered from layout rather than hand-maintained in one central file. Reproduce it with one routes/modules.php that iterates module providers, or simply let each module's loadRoutesFrom self-register. Verify with php artisan route:list after every addition — the same way you would run debug:router.

Testing per module. Write a functional test per module route ($this->get('/billing/invoices')->assertOk()), which pins down the implicit conventions. If you are on the native track, $client->request(...) against each module route does the same job and is the only reliable way to catch routing regressions caused by directory renames.

Legacy native maintenance. If you genuinely are on Symfony2 with this bundle: add one module per feature, keep each module's config and routing inside the module folder, and never import module internals from another module — the package has no isolation guarantees, so you enforce them by convention. Clear and rebuild the cache after every structural change; treat it as part of the edit-test loop.

Gotchas and Tips

  • No Laravel integration path exists. A Symfony-to-Laravel bridge would mean reimplementing bundle registration, DI wiring, routing, config merging, and autoloading. That is a custom adaptation project, not an integration. Reject it as a dependency.
  • Abandonment is the headline risk. Symfony2 is EOL, and this bundle predates Symfony 3+. There is no security maintenance and no community to absorb a CVE. With 15 stars and zero dependents, you would be the only maintainer — unpaid and off the clock.
  • Autoload era mismatch. The code likely targets PSR-0. PSR-4-only modern Composer setups can silently fail to find classes; if you must run it, add an explicit autoload mapping to the root composer.json and composer dump-autoload -o afterwards.
  • Cache is aggressive and opaque. After adding or renaming a module, rm -rf app/cache/* (or app/console cache:clear) before rebuilding. Routing and container caches will otherwise serve stale definitions, and the failure surfaces as a 404 or a "service not found" rather than a clear "your module isn't loaded" message.
  • Silent failure modes over loud ones. Container/service-resolution ordering problems and routing convention mismatches often present as a blank page or a wrong route, not an exception. Debug in this order: debug:router → container:debug → clear cache → read the DI extension's load() again.
  • Package discovery will not find it. extra.laravel.providers is a Laravel-only convention and this package does not declare it. If you install it beside Laravel expecting auto-registration, nothing happens and nothing tells you why.
  • Extension points, if you want to study it. The bundle class, the DI extension's load()/Configuration, and any compiler passes are the three places behavior is decided. In Laravel, the analogues are register()/boot(), mergeConfigFrom, and $this->app->extend() / container events. Study the former, implement the latter.
  • Pin exact versions if you are stuck on the native track. Old Composer constraints and PHP version requirements will resolve to something unexpected on a modern machine. Commit the composer.lock and note the PHP version in the repo, or the next developer loses a day to it.
  • Log it as technical debt, not an architecture choice. If this already exists somewhere in a codebase, the right ticket is containment plus a replacement plan — migrate to a maintained Symfony bundle, or port the module boundaries to native structure — not "expand usage."
  • The reusable takeaway is the convention, not the code. A few dozen lines of service-provider and directory convention gets you the same modularity with zero third-party risk and an open upgrade path. Steal the pattern; skip the package.
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.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect