Una narrativa del uso de Composer en un complemento de WordPress

Publicado: 2015-07-06

petersuhm Esta pieza fue aportada por el autor invitado Peter Suhm. Peter es un desarrollador web de la tierra de los daneses. Es el creador de WP Pusher y un gran adicto a los viajes, y lleva consigo su trabajo a medida que avanza.


El otro día publiqué una advertencia sobre el uso de Composer en complementos de WordPress en el blog de WP Pusher. Esta publicación llamó mucho la atención y siento la necesidad de aclarar algunos puntos que no estaban del todo claros para todos. El artículo también fue un poco pesado en aspectos técnicos, por lo que en esta publicación intentaré aclarar mi punto principal usando una narración simple para ilustrarlo.

Una narración

Crédito de la foto: Doors Open Toronto 2008 - Archivos de Toronto - (licencia)
Crédito de la foto: Doors Open Toronto 2008 – Archivos de Toronto – (licencia)

Imaginemos por un momento que tú y yo somos autores de complementos. Ambos tenemos una gran idea para un complemento que deseamos distribuir a través de WordPress.org. Queremos incluir algunas funciones premium en nuestros complementos que los usuarios de la versión gratuita pueden desbloquear ingresando una clave de licencia.

Necesitamos algún código que pueda manejar este proceso. Ambos nos damos cuenta de que este problema probablemente ya lo haya resuelto otra persona. Ninguno de nosotros es fanático de reinventar la rueda, así que nos dirigimos a Packagist y escribimos "administrador de licencias". Parece que nuestra suposición estaba justificada. Yoast ya tiene un paquete que puede manejar esto. Ambos decidimos hacer un composer require yoast/license-manager . Pan comido. Ahora podemos pasar a trabajar en algo que realmente importa: las características principales de nuestros respectivos complementos.

Avance rápido, listo para lanzar su complemento, se da cuenta de algo: su usuario no necesariamente tiene Composer a mano cuando instala su complemento desde WordPress.org, entonces, ¿cómo van a obtener el código para el administrador de licencias? Esta situación es un poco molesta, porque la única solución que realmente ve es simplemente enviar todo el directorio de vendor generado por Composer a su complemento y enviarlo a WordPress.org. Sabes que no es así como se supone que funciona Composer, pero lo que sea. Realmente no tienes otras opciones.

Mientras tanto, he llegado a la misma conclusión con mi complemento. Simplemente incluya el código del administrador de licencias y listo.

Avance rápido una vez más, nuestros complementos ahora se encuentran en el repositorio de WordPress.org y, de vez en cuando, alguien decide actualizar a nuestras versiones premium. Todo parece estar bien y ambos estamos agradecidos de poder usar el código que Yoast generosamente abrió y no tuvimos que reinventar la rueda.

Un día, recibes un extraño correo electrónico. Un cliente está experimentando un comportamiento realmente extraño cuando intenta desbloquear sus funciones premium. No tiene sentido para ti, porque nadie más informó esto. Después de horas de depuración, finalmente le pide a su cliente que desactive todo lo demás, excepto su complemento, y luego: ¡Funciona! Mmm. Su complemento parece ser de alguna manera incompatible con otro complemento. Mi complemento.

Te das cuenta de esto después de horas de revisar el código fuente de todos los demás complementos que el cliente había instalado. Cuando te das cuenta de que ambos usamos el administrador de licencias, suena una campana. ¿Podría ser esto realmente? Si es así, ¿cómo es que no hay fatal errors: cannot redeclare class ?

Una semana antes, pasé la versión requerida del administrador de licencias en mi complemento a la última versión, que incluía algunos cambios importantes (ficticios). Después de aún más depuración y var_dump() , te das cuenta de que mi versión del administrador de licencias también es la versión cargada por PHP en tu complemento. Lo encuentras realmente extraño porque específicamente requerías otra versión del administrador de licencias con Composer. Realmente no sabes qué hacer con esto.

Porque realmente no hay mucho que puedas hacer al respecto.

¿Que pasó aquí?

Ahora que todos hemos visto el problema, tomemos un momento para repasar lo que realmente sucedió en la narración. En primer lugar, ¿por qué PHP no causó un error fatal cuando dos clases obviamente tenían el mismo nombre que ambos incluimos en el administrador de licencias?

La razón de esto es que usamos un cargador automático generado por Composer. Este autocargador escanea la estructura de directorios de nuestras dependencias y agrega cada clase al autocargador. Si ya se ha agregado una clase, Composer la ignorará. Silenciosamente. He escrito un pequeño ejemplo de código si quieres verlo por ti mismo. Está en GitHub.

¿Por qué se incluyó mi versión del administrador de licencias antes que la suya?

Esto sucedió porque mi complemento tenía un nombre que provocó que se cargara antes que el tuyo. ¡Tal vez, en el futuro, todos nombraremos a nuestros complementos "Aaaaa My Plugin" para que se carguen primero!

Entonces, para resumir, el problema principal aquí es que no sabremos qué versión de nuestras dependencias están disponibles para nosotros en qué momento. Simplemente depende de factores que no podemos controlar completamente como desarrolladores de complementos.

¿Es este un problema específico de Composer?

No. Realmente no lo es. WordPress no tiene forma de lidiar con código de terceros en complementos o temas. Ahí yace el problema. La razón por la que estoy hablando de Composer es que está ganando mucha tracción en estos días. Si los desarrolladores de WordPress quieren usar Composer en complementos lanzados a través de WordPress.org, esto debe resolverse de alguna manera. De lo contrario, veremos un verdadero caos cuando todos los complementos comiencen a ser incompatibles entre sí porque usan versiones diferentes. Bienvenido al infierno de la depuración.

¿Qué podemos hacer al respecto?

Alguien que se ha preocupado mucho por esto y ha trabajado duro para encontrar una posible solución es Coen Jacobs. Decidí comunicarme con Coen y preguntarle si cree que hay algo que podamos hacer al respecto.

Muchos desarrolladores ya están incluyendo código de terceros en sus complementos. ¿Es esto realmente un problema?

Sí, esto ya es un problema en el ecosistema de complementos. Será aún peor cuando más personas descubran que es una buena idea poner la funcionalidad común en paquetes separados. Estos paquetes se pueden agrupar con múltiples complementos y el problema aparecerá cada vez más. He estado hablando con un par de desarrolladores que ya han pasado por un infierno de depuración tratando de averiguar qué está causando este problema.

En el futuro, ¿sugerirías que los desarrolladores dejen de incluir código de terceros en sus complementos?

Estoy un poco desgarrado con este tema. No tiene sentido desde el punto de vista de los desarrolladores decirle a la gente que deje de agrupar paquetes compartidos en sus complementos. Por otro lado, todos quieren la mejor experiencia de usuario posible para sus usuarios. Es una decisión difícil de tomar con seguridad.

En este punto, quiero impulsar el desarrollo relacionado con WordPress. Quiero compartir bibliotecas y usar bibliotecas compartidas por otros. Nadie debería estar reinventando la rueda una y otra vez. Así que me arriesgaría a encontrarme con problemas como este, resolviendo los problemas a medida que aparecen.

Esto también significa que haré todo lo posible para encontrar una solución a largo plazo para este problema. Más personas comenzarán a usar Composer, más personas incluirán bibliotecas con sus complementos. Este problema aparecerá con más frecuencia, por lo que es hora de solucionarlo.

¿Qué pueden hacer los desarrolladores de complementos para evitar este problema?

Hay una solución alternativa que he visto que algunas personas ya usan. Básicamente se trata de mover su dependencia al espacio de nombres de su complemento. Danny van Kooten hizo esto para uno de sus complementos. Sin embargo, esto no es lo ideal. Cada vez que actualiza sus dependencias, tiene que revisar todos los archivos y cambiar los espacios de nombres nuevamente. Ahora bien, esta no es una tarea tan grande para una biblioteca relativamente pequeña como Pimple, pero sí una tarea enorme para bibliotecas más grandes.

Sin embargo, esto solo se puede hacer con espacios de nombres, por lo que también deberá hacer que su complemento requiera PHP 5.3+. No voy a mentir, creo que todos los complementos deberían comenzar a hacer eso tarde o temprano, pero definitivamente es algo que debes considerar cuando decidas hacer esto.

¿Cuál sería la solución ideal, si la hay?

La situación ideal sería usar algún tipo de administrador de dependencias. Por supuesto, está Composer, el administrador de dependencias más utilizado. Composer es muy difícil, si no imposible, de usar para la gran mayoría de los usuarios de WordPress. Después de todo, es una herramienta para desarrolladores.

WordPress debería hacer esto más fácil para sus usuarios finales, al mismo tiempo que permite a los desarrolladores utilizar prácticamente cualquier paquete que deseen. Con este pensamiento, comencé a armar el complemento de instalación de WordPress Composer, que hace todo el trabajo duro de Composer mientras las personas instalan los complementos como siempre lo han hecho. Tan pronto como pueda terminar esto, lo integraré correctamente en todo el flujo de instalación del complemento.

Ahora, tal vez algún día, esto se pueda integrar en el núcleo de WordPress. Tiene un largo camino por recorrer, pero la prueba de concepto ya funciona.

Conclusión

Si has estado leyendo hasta aquí, antes que nada: Gracias. En segundo lugar, espero que ahora vea cómo esto es algo que eventualmente se convertirá en un problema. Nuestra situación actual es muy frustrante, porque simplemente no tenemos las herramientas que necesitamos. Aún así, creo que es importante que sigamos hablando de esto y nos aseguremos de que todos, como desarrolladores de WordPress, comprendamos los posibles problemas causados ​​por las dependencias de terceros en conflicto en nuestro código.

Finalmente, quiero mencionar una vez más que este no es un problema de Composer. Es un problema de WordPress.