Primeros pasos para la creación de un proyecto de package para Composer. Como inicializar el proyecto, qué archivos y carpetas debería contener y cómo gestionar dependencias y autoload de clases.
A día de hoy la mayoría de los desarrolladores de PHP utilizan "composer" para gestionar las dependencias de sus proyectos. Si desarrollas en PHP y todavía no estás usando composer probablemente es que no te dedicas de manera profesional al mundo del desarrollo. Tampoco es un problema porque siempre estás a tiempo te beneficiarte de esta fabulosa herramienta.
En otros artículos del manual de Composer de DesarrolloWeb.com hemos explicado cómo lo puedes usar para trabajar con las dependencias de tus proyectos o incluso utilizar su sistema de autocarga de clases. Pero lo que no hemos tocado todavía es como crear tus propios paquetes y publicarlos para que los use la comunidad utilizando composer
Crear un paquete puede ser una tarea más fácil de lo que esperabas y además te puede ofrecer numerosos beneficios. Entre ellos la posibilidad de utilizar tu software a lo largo de varios proyectos, sin necesidad de copiar y pegar todo el tiempo los archivos necesarios. A la vez te permite beneficiarte de las mejoras que realices en los packages en todos los lugares donde los uses, simplemente actualizando la dependencia con un sencillo comando. Pero además servirá para aportar tu granito de arena en la comunidad de PHP y quién sabe tener un perfil de desarrollador más conocido en el sector.
Instalación de Composer
El primer paso consiste en instalar composer, si no lo tenemos ya en nuestro ordenador. El paso de la instalación no lo vamos a ver en este artículo porque ya lo hemos abordado anteriormente en este manual. Puedes consultar el artículo sobre instalación de composer para más información.
Creación del proyecto de package
La creación de un proyecto para albergar el paquete consiste simplemente en crear una carpeta en tu ordenador para guardar los archivos que quieras compartir.
Posteriormente en tu carpeta necesitarás inicializar el proyecto con composer, para lo que lanzarás el comando:
composer init
Entonces aparecerás en un asistente que te solicitará paso a paso toda la información para inicializar tu proyecto, comenzando por el nombre del package, tal como puedes ver en la siguiente imagen.
El nombre del package consiste en dos secciones separadas por una barra inclinada. La primera sección corresponde con el "vendor", que es la empresa o desarrollador que ha creado el package. La segunda sección corresponde al nombre del proyecto en sí que se está desarrollando.
Como podrás ver el propio asistente de inicialización del proyecto de composer de ofrecer algunas configuraciones predeterminadas que puedes aceptar simplemente pulsando la tecla Enter.
La mayoría de las preguntas que te va a realizar el asistente te resultarán perfectamente entendibles, aunque hay algunas otras que no son tan claras y vamos a comentar:
Definir las dependencias (define your dependencies)
Cuando te pregunte si quieres definir dependencias interactivamente puedes decirle que no, simplemente colocando una letra "n" y pulsando la tecla Enter. Simplemente es porque quizás no necesitas dependencias, o bien porque las podemos instalar un poquito más tarde con comandos de consola.
Lo mismo ocurre con las dependencias de desarrollo "dev dependencies", que podemos instalar más tarde según vayamos necesitándolas.
Añadir PSR-4 para autoload
Hay otra pregunta quizás menos clara que dice así:
Add PSR-4 autoload mapping? Maps namespace "Midesweb\ValidationHelpers" to the entered relative path. [src/, n to skip]:
Esto quiere decir que, si lo deseas, puede añadir la configuración necesaria para que tus clases se encuentren en un espacio de nombres determinado y se puedan cargar automáticamente con el autoload de composer PSR-4.
Generalmente esto lo querrás sí o sí para que tus packages se puedan usar de la manera en la que los desarrolladores lo esperan. Lo que puedes configurar en este punto es la ruta de tu proyecto donde deberán localizarse las clases.
El valor que te sugiere de manera predeterminada es "src/", que es el típico en los packages de Composer, por lo que te sugerimos que lo aceptes tal cual.
Por si no entiendes exactamente qué es lo que implica este punto, lo vamos a ver con un ejemplo:
Ponte que tienes una clase en este namespace: Midesweb\ValidationHelpers y se llama MagnificValidator.
Entonces Composer esperará encontrarla en el archivo con la ruta: src/MagnificValidator.php.
Entonces, la ruta completa de la clase con el espacio de nombres sería Midesweb\ValidationHelpers\MagnificValidator.
Generación del composer.json
Una vez has terminado de contestar todas las preguntas del asistente se generará un archivo llamado composer.json que es el que contiene toda la información del package que estás creando.
Lo verás en la carpeta del proyecto donde estabas situado en el terminal.
Estructura de carpetas de tu proyecto
Cuando trabajes en el desarrollo de un package para composer y lo ideal es que establezcas una estructura de carpetas predecible y estándar.
Una de las decisiones de esta estructura del proyecto la tomado ya en el paso anterior, cuando le dijimos que las clases del proyecto se colocarían en la carpeta "src". Pero generalmente esta no será la única carpeta que tendrás puesto que al menos en tu package deberías colocar también los test unitarios de tus clases.
Lo típico es que tengas entonces la carpeta /src para tus clases y la carpeta /tests para ustedes unitarios o de funcionalidad.
Vamos a suponer que nuestro package contiene una clase que se llama "MagnificValidator" y por tanto el test de esta clase se llamaría "MagnificValidatorTest.php". Entonces, comenzaremos con una estructura de proyecto como se puede ver en la siguiente imagen:
En esa imagen verás varios archivos típicos del proyecto, entre los que se encuentra el típico README.md o .gitignore, etc. Esos archivos los encontrarás dentro de este proyecto de Magnific Validator en GitHub.
Usando también archivos con funciones
Ahora bien, si en tu package también quieres incluir otros archivos que tienen funciones, tendrías que acudir a otras normas para configurar el sistema de autoload.
Por ejemplo, puede que tengas un archivo llamado validator_helpers.php que has colocado también en la carpeta src.
En él podrías tener definiciones de funciones sueltas como:
<?php
function mgcValidateEmail(string $email): bool {
return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
}
Entonces en el autoload de composer tendrías que configurar ese archivo de la siguiente manera:
"autoload": {
"psr-4": {
"Midesweb\\ValidationHelpers\\": "src/"
},
"files": [
"src/validator_helpers.php"
]
}
Esta configuración es perfectamente posible pero tiene algunos detalles a considerar:
- El array "
files" delcomposer.jsonsolo permite indicar archivos sueltos. De modo que si tienes varios archivos con definiciones de funciones deberías indicarlos por separado. En otras palabras, no existe la manera de asociar todos los archivos de una carpeta, por ejemplo, a la configuración "files". - Todas las rutas en el array "
files" deben ser realizadas de manera relativa al lugar donde tienes elcomposer.json. - A la hora de hacer el autoload los desarrolladores que utilicen tu package tendrán declaradas las funciones de modo global. Es por ello que tienes que tener cuidado para que no se produzcan colisiones. Algo típico sería colocarles un prefijo en los nombres de las funciones, para asegurarte que los nombres que utilices sean únicos. En otras palabras, es preferible llamar a la función
mgcValidateEmail()quevalidateEmail(), para asegurarte que no colisiona. - Como sugerencia, evalúa la posibilidad de usar métodos estáticos de clases en lugar de funciones, porque así te ahorras la incomodidad de ocupar espacios de nombres globales.
Generar el sistema de autoload de composer
Cuando cambias el composer.json en lo que respecta al sistema de autoload, ya sea en las configuraciones "files" o bien en "psr-4", tienes que lanzar un comando que regenera la autocarga:
composer dump-autoload
Generalmente cuando instalas dependencias este autoload se regenera automáticamente, pero si cambias algo sin instalar dependencias no ocurrirá. Por eso preferimos mencionarlo.
Instalar dependencias en tu package
A la hora de desarrollar nuestro paquete de composer podemos necesitar dependencias de terceros, que deberían instalarse vía composer en el proyecto.
Vamos a comenzar instalando una dependencia necesaria para todos los paquetes que sería la que nos permite realizar los test unitarios de las clases que vamos a desarrollar.
En este caso vamos a utilizar PHPUnit como framework de test, por lo que instalaríamos la dependencia del siguiente modo:
composer require phpunit/phpunit --dev
En este caso estamos instalando con el flag --dev porque se trata de una dependencia de desarrollo. Es decir, usaremos PHPUnit durante la etapa de desarrollo pero no es algo que necesiten las personas que vayan a usar este package en producción.
Inicializar un repositorio Git
Otra cosa que no puede faltar en el flujo de publicación de un package para composer es la creación de un repositorio Git, donde mantendremos el control de versiones del proyecto de software.
Más adelante veremos con Git cómo hacer operativas más complejas y cómo apoyarnos en esta herramienta para definir las versiones del package. De momento lo que queremos hacer es simplemente inicializar el repositorio y crear el archivo .gitignore.
Inicializamos el repositorio con el siguiente comando:
git init
Por supuesto, para lanzar ese comando debes tener Git instalado. Consulta el manual de Git para más información
Luego es importante que creemos el archivo .gitignore que nos servirá para declarar qué archivos o carpetas queremos evitar que se suban al repositorio.
De momento, el código mínimo que debería tener el archivo .gitignore es este:
vendor
Esto hace que se ignore la carpeta "vendor" que tenemos en la raíz del proyecto, donde Composer instala las dependencias.
Ya dependiendo del proyecto, o del sistema operativo con el que trabajemos, puede que sea necesario añadir otros archivos o carpetas, pero eso ya lo dejamos para tu parte. Consulta el artículo sobre el archivo .gitignore para más detalles.
Vídeo de publicar un package con Composer
En este vídeo vas a ver el proceso completo de publicar un package con Composer, que incluye todos los pasos que hemos comentado en este artículo y algunos adicionales que veremos en las próximas entregas.
Miguel Angel Alvarez
Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...