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

Modules Laravel Package

zxf/modules

zxf/modules is a Laravel package for organizing applications into self-contained modules, with support for module discovery, service providers, routes, configuration, migrations, and views. It helps keep large Laravel codebases structured and maintainable.

View on GitHub
Deep Wiki
Context7

Getting Started

First, confirm the package is installed and discoverable in Laravel 11+ on PHP 8.2+:

composer require <vendor>/<package>
php artisan vendor:publish --tag=<package-config>
php artisan list

Look first at the published module configuration. This package is config-driven rather than JSON-driven: module enablement, paths, route prefixes, middleware groups, controller namespace mapping, views, migrations, commands, and events are controlled from config.

Your first day-to-day use case should be creating or enabling one module and wiring a simple route, controller, and view:

  1. Create a module using the package’s generator command. Find the exact command name with php artisan list and look for module/make commands.
  2. Register or enable the module in config.
  3. Add a controller and route in the module’s expected directory structure.
  4. Add a view and reference it with the module view namespace, e.g. blog::list.test.
  5. Run the package’s module info/validation commands to confirm discovery, routing, and namespace mapping.
  6. Clear caches after config changes:
php artisan optimize:clear

The package’s main value is reducing boilerplate for multi-module Laravel applications. Use it when you want modules to own their routes, views, config, migrations, commands, and service providers while still using Laravel’s normal container, routing, and Eloquent behavior.

Implementation Patterns

Config-driven module registration

Keep module definitions in config and treat module enable/disable as an operational concern. Disabled modules should not load routes, providers, commands, or other components. This is useful for staging environments, feature rollout, and local development where only a subset of modules is needed.

Module-local Laravel components

Structure each module like a small Laravel slice:

Modules/Blog/
├── Config/
├── Console/
├── Http/
│   └── Controllers/
├── Models/
├── Providers/
├── Resources/
│   └── views/
├── Routes/
└── Database/
    └── Migrations/

Use the package’s auto-discovery for service providers, routes, commands, and similar components. Avoid manually registering everything in AppServiceProvider unless you need behavior the package does not cover.

Dynamic route prefixes and names

Let module config drive route prefixes and route name prefixes. A blog module can expose routes such as:

Route::get('/posts', [PostController::class, 'index'])
    ->name('posts.index');

with the package applying the configured prefix and name prefix. This keeps module routes portable across applications and environments.

Controller namespace mapping

Use route controller namespace mapping when modules use different controller namespaces or when route files should remain stable while namespace conventions change. This is especially useful when migrating existing modules into the package structure.

Module-aware request/current module detection

The release adds improved module_name support for retrieving the request module and current module name. Use this in middleware, request macros, logging context, permissions, and module-specific configuration lookups rather than parsing URLs manually.

Typical pattern:

$module = module_name();

or, where request context is needed, use the package’s current/request module helper in middleware or controllers. Prefer package helpers over hard-coded module names.

View namespaces

Use module view namespaces consistently:

return view('blog::list.test');

This keeps views isolated and avoids collisions between modules.

Migrations and module lifecycle

Use the package’s migration commands for module-owned migrations. Day-to-day workflow:

php artisan migrate
php artisan <package>:migrate-status

When adding a module, run the package’s module info/validation commands before debugging route or provider issues. Check module status first, then route registration, then namespace mapping.

Helper functions

The package provides 40+ helpers, many callable without arguments. Use them for common module lookups instead of duplicating path/name logic. Establish a small internal convention for your team: use package helpers for module name, module path, current module, and route/view namespace resolution.

Query macros

The package includes query macros such as whereHasIn, orWhereHasIn, whereHasNotIn, random, and groupRandom. Use these for common relationship filtering and random selection patterns, but wrap them in repository/query scopes if they become central to your domain logic.

Command-driven module workflow

Use the new command tooling for module creation, inspection, validation, and migration status. Keep a short team checklist:

php artisan <package>:module-info
php artisan <package>:module-validate
php artisan <package>:migrate-status
php artisan optimize:clear

Exact command names should be confirmed with php artisan list for the installed version.

Gotchas and Tips

Clear caches after config changes

Because routing, view namespaces, provider discovery, and module enablement are config-driven, stale caches can make it look like a module is missing or routes are not registered. Run:

php artisan optimize:clear

after changing module config, renaming module config files, or enabling/disabling modules.

Check config file naming conventions

This release adds compatibility for module config files using camelCase/lowercase module names such as blog.php, as well as fixed config.php mode. If module config is not being read, verify which mode your application uses. Do not assume Config.php, config.php, or blog.php are interchangeable without checking the package’s expected convention.

Module name helpers may behave differently by context

The new module_name support distinguishes request module and current module name. In middleware, queued jobs, console commands, and tests there may be no HTTP request context. Avoid calling request-dependent helpers in CLI or queue code unless you have verified behavior; use explicit module context where possible.

File system exceptions

The release fixes file system exception issues. After upgrading, verify filesystem permissions and published config paths. If you previously worked around file system errors, remove stale workarounds and test module discovery, view compilation, and migration paths.

Base class request exceptions

The release fixes base class Request exceptions and improves base class naming readability. If you extended internal base classes, re-check your subclasses after upgrading. Prefer public package APIs and helpers over extending internal classes unless necessary.

Disabled modules should be truly disabled

When disabling a module, confirm that its routes, providers, commands, and migrations are not loaded. Test with:

php artisan route:list
php artisan about

and the package’s module info command. If disabled modules still appear, check config cache and module discovery paths.

Route/controller namespace mismatches

Dynamic route prefixes and controller namespace mapping are powerful but can hide naming mistakes. If a route resolves to the wrong controller or a 404 appears after renaming a module, check:

  • module config key
  • route file location
  • controller namespace
  • route name prefix
  • route middleware group
  • cached routes

View namespace collisions

Use unique module names and consistent view namespaces. A module named Blog should be referenced consistently, e.g. blog::..., based on package conventions. Avoid mixing module names and route prefixes as if they are the same thing.

Migration ownership

Module migrations can be easy to lose track of. Always use the package’s migration status command and verify migration paths after moving modules or changing module directories.

Multiple module scan paths

The package supports multiple module directories. If a module is not discovered, check every configured scan path and ensure directory naming matches the package’s expected convention. Do not debug only the default Modules/ directory.

Helper overuse

Forty-plus helpers are convenient, but scattering them through domain code can make testing harder. Keep module-aware helper calls near the framework boundary: middleware, controllers, service providers, and route files. Pass explicit module names or context into domain services.

Upgrade checklist for v1.13.10

After upgrading:

composer update <vendor>/<package>
php artisan optimize:clear
php artisan <package>:module-info
php artisan <package>:module-validate
php artisan route:list
php artisan migrate

Then test one enabled module and one disabled module. Pay particular attention to module config file naming, request/current module helpers, view namespaces, route registration, and any custom classes extending package base classes.

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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
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
cgv/localized-resource