Cuando trabajamos con Elixir, llega un momento en que necesitamos reutilizar código para no repetirnos una y otra vez en distintos proyectos. Por ejemplo, imaginemos que estamos desarrollando una aplicación para una empresa que realiza cálculos financieros como impuestos, retenciones o salarios. Si después de un tiempo creamos otro proyecto similar para otro cliente, copiar y pegar el código de un proyecto a otro puede ser tedioso y propenso a errores, especialmente cuando hay que corregir o actualizar alguna fórmula.
Aquí es donde entran en juego las dependencias. En Elixir, una dependencia es un proyecto externo que podemos incluir en el nuestro para aprovechar su funcionalidad sin tener que reescribirla. Cuando compilamos nuestro programa, no solo se incluyen los módulos que hemos creado en la carpeta lib, sino también todos los módulos de las dependencias que hayamos declarado. Esto es similar a cómo usamos las funciones básicas de Elixir, que forman parte del paquete principal, pero si queremos funcionalidades adicionales, podemos traer librerías externas.
El repositorio principal donde la comunidad de Elixir y Erlang publica sus librerías es Hex.pm. Allí podemos encontrar paquetes gratuitos y de código abierto, así como opciones premium para almacenar paquetes privados, útiles para equipos de trabajo que quieran compartir librerías internas sin hacerlas públicas. Para la mayoría de los casos, la variante open source es suficiente y es donde encontraremos la mayoría de las librerías comunitarias.
Un ejemplo clásico es la librería Jason, que nos permite convertir entre mapas de Elixir y cadenas JSON de forma sencilla. En lugar de implementar manualmente estas conversiones, simplemente añadimos Jason como dependencia y podemos usar sus funciones para codificar y decodificar JSON.
Para declarar una dependencia en nuestro proyecto, debemos editar el archivo mix.exs. En la función project encontramos una clave llamada deps que es una lista con las dependencias que queremos usar. Cada dependencia se representa como una tupla con dos elementos: el nombre de la dependencia como átomo, por ejemplo :jason, y la versión que queremos usar como cadena de texto.
Las versiones son importantes porque las librerías evolucionan con el tiempo, corrigiendo errores y añadiendo mejoras. En Hex.pm podemos ver el historial de versiones de cada paquete y elegir cuál queremos usar. Para evitar que nuestro código deje de funcionar de repente por cambios incompatibles, fijamos la versión o la familia de versiones que queremos aceptar. Por ejemplo, podemos indicar que queremos usar cualquier versión dentro de la familia 1.2.x de Jason, lo que nos permite recibir correcciones menores sin saltar a una versión mayor que podría romper compatibilidad.
Cuando ejecutamos el comando mix deps.get, Mix descarga todas las dependencias declaradas y las coloca en la carpeta deps. No debemos modificar manualmente esta carpeta, ya que Mix la gestiona automáticamente. Al compilar o ejecutar nuestro proyecto, las dependencias estarán disponibles para usar sus módulos y funciones.
Por ejemplo, tras añadir Jason como dependencia, podemos usar funciones como Jason.encode/1 para convertir un mapa a JSON, o Jason.decode/1 para hacer la operación inversa. Esto nos permite escribir programas más serios y completos sin reinventar la rueda.
Además de Jason, en Hex.pm encontramos muchas otras librerías populares. Por ejemplo, Ecto es un ORM muy utilizado para trabajar con bases de datos, facilitando la transformación entre filas y estructuras de Elixir. También está Phoenix, el framework web más popular en Elixir, y librerías para bots de Discord como Alchemy o para trabajar con GraphQL como Absinthe. La elección de dependencias dependerá de las necesidades específicas de cada proyecto.
En definitiva, gestionar dependencias en Elixir con Mix y Hex.pm es fundamental para mantener nuestros proyectos organizados, evitar duplicidades y acelerar el desarrollo aprovechando el trabajo de la comunidad.