modularize / laravel-modules
Modular architecture for Laravel applications with automatic scaffolding for Web and API
Requires
- php: ^8.2
- laravel/framework: ^12.0
- nette/php-generator: ^4.1
- nikic/php-parser: ^5.5
Requires (Dev)
- orchestra/testbench: ^10.0
- phpunit/phpunit: ^11.0
- squizlabs/php_codesniffer: ^4.0
This package is not auto-updated.
Last update: 2026-04-03 14:56:16 UTC
README
Laravel Modularize es un paquete independiente (framework-agnostic) que permite crear arquitecturas modulares, limpias y altamente desacopladas dentro de aplicaciones Laravel 11 y 12+. Diseñado específicamente para proyectos Enterprise y Domain-Driven Design (DDD), se aleja del monolito MVC tradicional para organizar la lógica de forma funcional (por Módulos).
Proporciona generadores CLI inteligentes para inicializar ciclos CRUD completos, incluyendo rutas anidadas, inyección de tareas programadas y variantes de scaffolding específicas para APIs o Web tradicional.
🚀 Características
- Arquitectura Desacoplada: La lógica se estructura funcionalmente en Módulos que encapsulan sus propios Modelos, Controladores, Requests, Vistas, Migraciones, etc.
- Auto-Bootstrapping: Cada Módulo actúa como su propio Service Provider—cargando automáticamente Rutas, Archivos de Configuración, Migraciones, Vistas y Comandos de Consola sin esfuerzo.
- Scaffolding Profundo (Web y API): Con un solo comando, puedes generar un Módulo entero, sus Módulos Hijos anidados, o una estructura completa que incluye métodos de Controlador, Modelos, Resources y rutas, afinados específicamente para endpoints API o portales Web clásicos.
- Abstracción de Namespaces: Se integra de forma nativa en cualquier aplicación sin depender de reglas rígidas basadas en la carpeta
app/. - 100% Testeado: Cobertura respaldada explícitamente por una rigurosa suite de pruebas montada sobre Orchestra Testbench y verificando los analizadores del árbol de sintaxis abstracta (AST) y generadores de archivos.
📦 Instalación (Local vía Path Repository)
Requisitos del Sistema
- PHP: 8.2, 8.3, 8.4, 8.5+
- Laravel: 11.x, 12.x
- nette/php-generator:
^4.1(Requerido obligatoriamente para soporte AST en PHP 8.4/8.5)
Hasta que el paquete sea registrado formalmente en Packagist, puedes instalarlo fácilmente de manera manual en cualquier proyecto de Laravel configurando un repositorio de ruta local.
Estos son los pasos para agregarlo a tu aplicación Laravel local:
Clona este paquete en un directorio junto a tu aplicación Laravel para que la estructura de carpetas se vea así:
/tu-workspace /mi-app-laravel <-- Tu proyecto real /modularize <-- Este paqueteEn tu proyecto de Laravel (
mi-app-laravel), abrecomposer.jsony añade un repositorio local:"repositories": [ { "type": "path", "url": "../modularize", "options": { "symlink": true } } ]Requiere el paquete ejecutando:
composer require modularize/laravel-modules @dev php artisan vendor:publish --tag=modularize-init(Opcional pero recomendado): Publica la configuración del módulo y los stubs personalizados si necesitas cambiar la clase base o los namespaces. El proveedor
ModulesServiceProvidersincronizará los archivos necesarios (ej:AppModulo.stub) hacia tu carpeta de stubs de la aplicación.php artisan vendor:publish --provider="Modularize\ModulesServiceProvider"
🛠 Uso y Comandos
Todos los comandos de Laravel Modularize están diseñados para ser amigables tanto para automatización como para humanos.
[!TIP] Modo Interactivo: Si ejecutas cualquier comando de terminal enumerado abajo y omites parcialmente (o enteramente) los parámetros (por ejemplo, si simplemente ejecutas
php artisan modularize:make:scaffold), la consola entrará en modo interactivo y te guiará paso a paso preguntándote los valores que faltan (nombre del módulo, modelo a usar, etc) presentándote menús desplegables para elegir.
1. El poder de make:scaffold
Genera un ecosistema de andamiaje (scaffolding) completo para un concepto específico en un solo paso. Creará el archivo del Módulo Principal, el Modelo, el Resource, las clases Request para validación, el Controlador (alojado en la raíz matemática del módulo), la nueva capa lógica Business, y acoplará sus rutas al árbol de ejecución automáticamente.
A) Para Backends de API (RESTful)
Añade el flag --api. Esto omitirá el código pensado para vistas visuales (como los métodos create y edit) y automáticamente generará código listo para devolver respuestas JSON utilizando los API Resources.
php artisan modularize:make:scaffold --module=app --name=Blog --modelName=Post --api
B) Para Portales Web Clásicos (Blade / Vistas)
php artisan modularize:make:scaffold --module=app --name=Blog --modelName=Post
2. Scaffolding de Campos Interactivo (Estilo Rails)
Al generar andamiajes (make:scaffold) o modelos independientes (make:model, make:migration, etc.), puedes definir la estructura de la base de datos directamente desde la consola usando una sintaxis inspirada en Ruby on Rails, pasándola mediante la opción --fields:
php artisan modularize:make:scaffold --module=app --name=Store --modelName=Product \
--fields="name:string:unique,description:text:nullable,price:integer,category_id:foreignId"
El paquete utiliza manipulación del Árbol de Sintaxis Abstracta (AST) mediante nikic/php-parser para inspeccionar y recodificar tus archivos en tiempo real, inyectando exactamente lo que necesitas.
Tipos Soportados y Modificadores
Soporta estructuralmente todos los tipos nativos de Blueprint de Laravel (string, text, integer, boolean, uuid, etc).
También soporta modificadores separados por otro ::
nullable: Marca la migración con->nullable()y cambia las reglas de Form Request a['nullable']en lugar de['required'].unique: Añade la restricción->unique()en la base de datos.
Generación Automática de Relaciones y Casos Límite (Edge Cases)
El paquete es lo suficientemente inteligente para inyectar métodos de relaciones de Eloquent directamente en tus Modelos.
Si declaras un campo de tipo foreignId o usas un nombre que termine en _id (ej. user_id:integer), el AST escribirá tu modelo así:
1. Modelos Simples (user_id / category_id)
Se abstrae y traduce directamente a:
public function user()
{
return $this->belongsTo(User::class);
}
Además, en la capa de base de datos apendizará automáticamente ->constrained().
2. Relaciones Multipalabra (android_device_id / assigned_user_id)
Al seguir un diseño de convenciones estrictas (PSR), el paquete parseará cualquier llave relacional compleja y generará la relación aplicando camelCase para el método, y StudlyCase para la clase. Por ejemplo, assigned_user_id:foreignId genera:
public function assignedUser()
{
return $this->belongsTo(AssignedUser::class);
}
3. Modificadores de Relación Avanzados y Cascada
Puedes inyectar métodos de relaciones adicionales directamente especificando el tipo de relación de Eloquent (hasOne, hasMany, belongsToMany, hasManyThrough, hasOneThrough).
Para las llaves foráneas (foreignId), el paquete aplica ->onDelete('cascade') por defecto para mantener la integridad relacional. Sin embargo, puedes sobreescribir este comportamiento delegándole distintas restricciones a la base de datos de esta forma:
user_id:foreignId:set null->->onDelete('set null')en la Migración.user_id:foreignId:restrict->->onDelete('restrict')en la Migración.user_id:foreignId:no action->->onDelete('no action')en la Migración.
Para las relaciones del Eloquent Model:
profile:hasOne-> methodprofile()con$this->hasOne(Profile::class)en el Modelo.roles:belongsToMany-> methodroles()con$this->belongsToMany(Role::class)en el Modelo.deployments:hasManyThrough:Environment-> Usa el tercer parámetro como modelo intermedio.
[!NOTE] Autocompletado Interactivo: Si olvidas pasar el parámetro
--fields, Laravel Modularize te presentará un "wizard" o asistente en la consola preguntándote si deseas escribir estos campos manualmente antes de continuar.
3. Generadores Artisan Disponibles
En lugar de usar los comandos generadores monolíticos de Laravel (make:controller), utiliza el prefijo modularize: para garantizar que los archivos se creen dentro del límite lógico y el namespace correcto de tu módulo.
[!TIP] Modo Interactivo por Defecto: ¡Puedes simplemente ejecutar
php artisan modularize:make:model(sin ningún argumento) y la consola te preguntará todo paso a paso, incluyendo los campos de la base de datosfieldsdinámicamente!
A continuación, la estructura detallada de cada generador. (Recuerda que todos los argumentos son opcionales y el asistente te los preguntará interactiva y escalonadamente si los omites).
make:module
Crea un archivo de clase Module principal o anidado que se auto-registra en su módulo padre.
Ejemplo:
php artisan modularize:make:module --module=app --name=Store
| Argumento | Descripción |
|---|---|
--module | La llave de registro del módulo padre (ej: app o app.blog). |
--name | El nombre del nuevo Módulo (ej: Store). |
make:scaffold
Genera un ecosistema CRUD completo (Controlador, Modelo, Migración, Request, Resource, Rutas integradas). Si no provees los campos, el asistente promptForFields() tomará el control.
Ejemplo:
php artisan modularize:make:scaffold --module=app --name=Blog --modelName=Post --api --fields="title:string:unique,body:text"
| Argumento | Descripción |
|---|---|
--module | La llave de registro del módulo padre donde se anidará el scaffolding. |
--name | El nombre del submódulo (ej: Blog). |
--modelName | El nombre de la entidad/Modelo principal (ej: Post). |
--api | (Flag) Si se provee, construye Controladores y Rutas estrictamente API (omite Vistas web create/edit). |
--fields | Cuerda (String) continua de campos interactivos estilo Rails. |
--css | Framework CSS a utilizar para Vistas Web (bootstrap, tailwind, plain). Si se omite, el asistente te lo preguntará. |
--confirm | (Flag) Si se provee, sobreescribe archivos existentes sin lanzar advertencias (ideal para automatización CI/CD). |
make:model
Genera un Modelo Eloquent alterando el AST para inyectar relaciones en el vuelo basándose en reglas sintácticas (_id / foreignId). Nota: Este comando ahora maneja centralmente y de forma segura la integración de la Migración, previniendo duplicados cuando se invoca a través del scaffold.
Ejemplo:
php artisan modularize:make:model --module=app --name=Order --fields="amount:integer,user_id:foreignId" --migration
| Argumento | Descripción |
|---|---|
--module | Módulo padre de destino. |
--name | Nombre del Modelo (ej: Order). |
--fields | String de campos procesados por el ModelCodeGenerator para deducir relaciones belongsTo y reglas $fillable. |
--migration / -m | (Flag) Si se indica, además del modelo creará su respectivo archivo de Migración basándose en los mismos campos y lo guardará en el Migrations/ del módulo. |
make:migration
Genera un archivo de base de datos inyectando los esquemas directamente mediante AST, insertando constrained(), nullable() y más, inteligentemente.
Ejemplo:
php artisan modularize:make:migration --module=app --name=create_orders_table --create=orders --fields="amount:integer,user_id:foreignId"
| Argumento | Descripción |
|---|---|
--module | Módulo objetivo para guardar el Schema. |
--name | Nombre final del archivo PHP de migración. |
--create | El nombre formal de la tabla en base de datos. |
--fields | Campos para generar la estructura Blueprint. |
--path | (Opcional) Ruta personalizada explícita para generar el archivo. |
make:request
Genera FormRequests mapeando automáticamente las definiciones de atributos de Rails a validaciones de Laravel clásicas (required, nullable, integer, etc).
Ejemplo:
php artisan modularize:make:request --module=app --name=StoreOrderRequest --fields="amount:integer:nullable"
| Argumento | Descripción |
|---|---|
--module | Módulo objetivo. |
--name | Nombre del Request Validator. |
--fields | Utilizado para inyectar automáticamente el arreglo (array) nativo de reglas de validación en el método rules(). |
make:resource
Genera un API JsonResource exponiendo las propiedades serializadas extraídas del schema.
Ejemplo:
php artisan modularize:make:resource --module=app --name=OrderResource --fields="amount:integer"
| Argumento | Descripción |
|---|---|
--module | Módulo objetivo. |
--name | Nombre del Resource. |
--fields | Atributos mapeados para construir el array predeterminado de toArray(). |
make:view
Genera las cuatro plantillas Blade principales (index, create, edit, show) y el layout base para un modelo, integrando automáticamente los formularios HTML interactivos y clases CSS dinámicas. Soporta nativamente la inyección de alertas de validación (@error).
Ejemplo:
php artisan modularize:make:view --module=app --name=Product --fields="title:string,price:integer" --css=bootstrap
| Argumento | Descripción |
|---|---|
--module | Módulo objetivo donde residirán las vistas (Views/). |
--name | Nombre del Modelo asociado (ej: Product). |
--fields | Los campos utilizados para generar dinámicamente las columnas de tablas (index) y etiquetas <input>/<select> de formularios (create/edit). |
--css | El motor CSS deseado. Opciones: bootstrap, tailwind, plain. Por defecto, si omites esto en modo interactivo, la consola te desplegará un menú para elegir. |
make:business
Genera una clase de capa intermedia (Business Logic) a nivel raíz del módulo, pre-configurada con un método estático listar() que abstrae paginación, filtros y ordenamiento.
Ejemplo:
php artisan modularize:make:business --module=app --name=Order
| Argumento | Descripción |
|---|---|
--module | Módulo objetivo. |
--name | Nombre para la clase Business (ej: Order). El archivo resultante será OrderBusiness. |
make:controller
Genera un archivo de Controlador estándar vacío pero perfectamente enlazado y namespacesado (Namespaced) en la raíz del módulo objetivo (sin subcarpeta interna Controllers/).
Ejemplo:
php artisan modularize:make:controller --module=app --name=OrderController
| Argumento | Descripción |
|---|---|
--module | Módulo objetivo. |
--name | Nombre final de la clase Controller. |
make:command
Acopla un comando custom de consola en el ecosistema particular de un Módulo. Ejemplo:
php artisan modularize:make:command --module=app --name=SyncOrdersCommand
| Argumento | Descripción |
|---|---|
--module | Módulo contenedor para el comando. |
--name | Nombre de la clase (terminará extendiendo de \Illuminate\Console\Command). |
make:factory
Genera un Database Factory pre-configurado para Faker. Capaz de leer el Modelo vía AST (ModelParser) si omites los campos.
Ejemplo:
php artisan modularize:make:factory --module=app --name=OrderFactory --modelName=Order
| Argumento | Descripción |
|---|---|
--module | Módulo objetivo. |
--name | Nombre de la clase Factory. |
--modelName | Nombre del Modelo a asociar. Si se omite, se preguntará interactivamente. |
--fields | String de campos a falsificar. Si se omite, se extraerán directamente del código de la clase del Modelo indicado. |
make:seeder
Genera un Database Seeder invocativo. Automatiza la instanciación de un Factory si le indicas un Modelo. Ejemplo:
php artisan modularize:make:seeder --module=app --name=OrderSeeder --modelName=Order
| Argumento | Descripción |
|---|---|
--module | Módulo objetivo. |
--name | Nombre de la clase Seeder. |
--modelName | (Opcional) Si se especifica, el Seeder autogenerado vendrá con Order::factory()->count(10)->create() listo. |
Manejadores AST Directos (add:route y add:schedule)
Inyectan nodos directamente en la sintaxis de clases ya provistas globalmente por un Módulo utilizando php-parser.
| Comando | Argumentos | Descripción / Objetivo |
|---|---|---|
add:route | --verb, --uri, --method-name | Acopla una nueva ruta REST en routes.php / api.php. |
add:schedule | --command-name | Se inyecta al final del registro crond/scheduler del Module.php. |
🧪 Testing
El paquete depende exclusivamente de Docker y PCOV para garantizar un entorno de pruebas y nativo sin afectar las configuraciones de sistema operativo de tu máquina local.
Para correr toda la suite de pruebas (tests de features e integración), simplemente usa docker-compose:
# Correr tests de forma limpia
docker compose up test
Para ver el reporte gráfico completo de cobertura de código (HTML Coverage):
# Generará el reporte HTML dentro de la carpeta `./coverage/` local
docker compose run --rm coverage
⚖️ Licencia
El paquete Laravel Modularize es software de código abierto licenciado bajo los términos de la licencia MIT.