Guía Práctica: Cómo Modificar una Dependencia de NPM con yarn patch

Abdiel Martinez |

Aprende a tomar el control y parchar node_modules directamente con el comando yarn patch para aplicar arreglos permanentes sin esperar un fix oficial.

¿Cuántas veces te ha pasado? Llevas un buen rato desarrollando, todo fluye, hasta que te topas con un error que no tiene sentido. Revisas tu código una y otra vez, pero no hay un punto y coma faltante ni un error de sintaxis. Después de un buen rato de depurar, te das cuenta de que el problema no viene de tu código, sino de una de las dependencias que estás utilizando en node_modules.

En ese momento, tienes varias opciones, y ninguna es ideal. Puedes buscar en los issues del repositorio a ver si alguien más ya lo experimentó, esperando encontrar una solución. Podrías intentar arreglarlo tú mismo y abrir un Pull Request, pero... ¿y si el repositorio parece abandonado? ¿O si simplemente necesitas el arreglo ahora y no puedes esperar a que lo aprueben y publiquen una nueva versión? Podrías, en un caso extremo, buscar otra librería.

Pero ¿y si no es un bug? A veces, simplemente quieres que una dependencia funcione de una forma ligeramente diferente. Una pequeña modificación que encaja a la perfección en tu proyecto.

Me ha ocurrido esa situación recientemente. Trabajando con react-native-google-places-autocomplete, me di cuenta de que tenía todo lo que necesitaba, pero un pequeño problema de tipado me estaba causando ruido. El repositorio lleva más de un año sin actualizaciones, así que esperar un fix oficial no era una opción. Sabía exactamente qué cambiar en el código fuente dentro de mis node_modules, pero... ¿cómo hacer ese cambio permanente sin que se pierda en el próximo yarn install?

Para estas situaciones, podemos utilizar yarn patch. Te contaré cómo lo uso para parchar mis dependencias en casos como los que te describí.

Manos a la obra con yarn patch

Lo primero que hay que saber es que este comando es una característica disponible a partir de Yarn 2+. No ahondaré en cómo instalarlo, pero si aún usas la versión 1, este es un buen motivo para darle una oportunidad a las versiones más recientes.

Lo primero que deberás hacer es ejecutar un comando como el siguiente:

yarn patch <Nombre de la dependencia>

Ejemplo:

yarn patch react-native-google-places-autocomplete

Al ejecutarlo, Yarn descomprime el código de la dependencia en una carpeta temporal y lo deja todo listo para que puedas editarlo. La salida en la terminal será algo parecido a esto:

➤ YN0000: Package react-native-google-places-autocomplete@npm:2.5.7 got extracted with success!
➤ YN0000: You can now edit the following folder: C:\Users\example\AppData\Local\Temp\xfs-ef75dfca\user
➤ YN0000: Once you are done run yarn patch-commit -s "C:\Users\example\AppData\Local\Temp\xfs-ef75dfca\user" and Yarn will store a patchfile based on your changes.
➤ YN0000: Done in 0s 29ms

En el mensaje te da la ruta a una carpeta temporal donde está el código fuente de la dependencia, listo para ser modificado.

Un pequeño tip 🤫: si usas VSCode, puedes abrir esa carpeta directamente desde la terminal con el comando code, así:

code C:\Users\<tu-usuario>\AppData\Local\Temp\xfs-ef75dfca\user

Editando con Cuidado: src vs. dist

Ahora viene la parte divertida: abres el código y haces los cambios que necesitas. En mi caso, fue ajustar una definición de tipos para que se alineara con mi proyecto.

Sin embargo, aquí hay una consideración importante. Dependiendo de cómo esté empaquetada la librería, es posible que no estés modificando el código fuente (src) original, sino el código ya transpilado y listo para producción (dist, build, lib...). Esto significa que si el código está minificado u ofuscado, hacer cambios puede resultar una tarea MUY complicada.

En la mayoría de los casos para arreglos pequeños, no es un problema. Pero si necesitas hacer una modificación compleja, quizás sea mejor clonar el repositorio original, hacer los cambios en el src y compilarlo tú mismo. En lo personal, editar el código que yarn patch me proporciona es más que suficiente.

Creando y Aplicando el Parche 🩹

Una vez que has terminado de ajustar el código y estás contento con el resultado, es hora de guardar tus cambios en un "parche". Vuelves a tu terminal y ejecutas el comando que Yarn te sugirió antes:

yarn patch-commit -s "C:\Users\example\AppData\Local\Temp\xfs-ef75dfca\user"

Al hacerlo, Yarn compara el código original de la dependencia con tu versión modificada y genera un archivo .patch que contiene únicamente las diferencias. Este archivo se guardará dentro de tu proyecto, en una ruta como esta:

.yarn/patches/react-native-google-places-autocomplete-npm-2.5.7-4936683d44.patch

Además, dentro de tu package.json verás que la línea de tu dependencia ha cambiado drásticamente. En lugar de un número de versión, ahora usa el protocolo patch::

"dependencies": {
  "react-native-google-places-autocomplete": "patch:react-native-google-places-autocomplete@npm%3A2.5.7#~/.yarn/patches/react-native-google-places-autocomplete-npm-2.5.7-4936683d44.patch"
}

Esto le indica a Yarn que, cada vez que instale esta dependencia, primero debe descargar la versión 2.5.7 y, acto seguido, aplicarle las modificaciones definidas en tu archivo .patch.

Para que todo surta efecto en tu entorno local, solo te queda ejecutar el comando de instalación:

yarn install

¡Y listo! Tu cambio ahora está aplicado en tus node_modules y persistirá en futuras instalaciones. Además, como el archivo .patch forma parte de tu repositorio, cualquier compañero que clone el proyecto y ejecute yarn install también tendrá la versión parchada.

Si quieres profundizar, te recomiendo echar un vistazo a la documentación oficial.

Desde que descubrí esta funcionalidad, mi forma de afrontar los problemas con dependencias ha cambiado por completo. Si te gustan estos trucos para optimizar tu flujo de trabajo, quizás te interese mi artículo sobre cómo acelerar la terminal con atajos de PowerShell.

Cuéntame, ¿alguna vez has tenido que modificar una dependencia directamente en node_modules? ¿Qué método usaste para que no se perdieran tus cambios? ¡Cuéntame tu experiencia en los comentarios!