> Manuales > Taller de Javascript

Cómo solucionar el típico problema cuando desarrollas librerías npm en local, evitando publicar versiones de prueba: Guía paso a paso de npm link y yalc.

Flujo de trabajo para desarrollo local de librerías npm con Yalc

En el día a día al usar nuestra librería de componentes dile-components a menudo tenemos que publicar o actualizar componentes, con nuevos requisitos que necesitamos cubrir en un sitio web o en una aplicación. Los componentes de dile-components están publicados en npm y nos permiten usarlos en todos los sitios que desarrollamos. Evitamos reinventar la rueda y cuando publicamos mejoras las podemos disfrutar en todas partes. Es genial, pero hay un problema de flujo de trabajo que se debe resolver.

Si alguna vez has tenido que desarrollar una librería de npm en paralelo con una aplicación que la consume, seguro que conoces bien esta situación que resulta bastante pesada:

  1. Haces un cambio en el código de la librería.
  2. Incrementas la versión y la publicas en npm (o en un registro privado).
  3. Vas a tu aplicación consumidora, actualizas la versión en el package.json y ejecutas npm install.
  4. Reinicias el servidor de desarrollo para probar el cambio.
  5. Te das cuenta de que cometiste un pequeño error tipográfico y tienes que repetir todo el proceso desde el paso 1.

Este flujo destruye tu productividad, ensucia el historial de versiones con releases innecesarias y te hace perder minutos valiosos en cada iteración. Por suerte, existen varias alternativas para agilizar este proceso y desarrollar completamente en local.

Voy a comentar las alternativas que existen para poder mejorar este flujo, aunque ya te adelanto que la que usamos es Yalc, pues es la que nos permite trabajar bien con nuestro repositorio, que es un monorepo y gestionar sin problemas las versiones. npm link la verdad es que puede mejorar los flujos pero a veces no resulta útil en todos los tipos de proyectos, o por lo menos nos ha dado problemas.

1. npm link: La alternativa nativa

Node.js incluye de forma nativa la herramienta npm link. Su funcionamiento se basa en crear enlaces simbólicos (symlinks) en tu sistema operativo que conectan la carpeta global de npm con tus proyectos locales.

Paso a paso

  1. Registra tu librería local: Ve a la raíz de la carpeta de tu librería y ejecuta:
npm link

Esto creará un enlace simbólico global hacia tu paquete. 2. Enlaza la librería en tu aplicación consumidora: Abre la terminal en la carpeta de la aplicación que consumirá la librería y ejecuta:

npm link nombre-de-tu-libreria

(Importante: usa el nombre que figura en el campo "name" del package.json de la librería, no el nombre de la carpeta). 3. Compilación continua (Watch Mode): Para ver los cambios reflejados al instante, deja ejecutándose un proceso de compilación automática en la carpeta de la librería:

npm run build -- --watch

El gran problema de npm link

Aunque es práctico para proyectos sencillos, npm link suele dar problemas cuando trabajas con librerías más complejas (por ejemplo, UI kits en React o Vue o Lit). Al usar enlaces simbólicos, los resolvedores de módulos a menudo cargan instancias duplicadas de ciertas dependencias (peer dependencies), lo que desencadena errores como el famoso "Invalid hook call" en React.

2. yalc: El estándar de oro para el desarrollo local

Para evitar los dolores de cabeza de los enlaces simbólicos existe yalc.

A diferencia de npm link, yalc actúa como un registro de npm local y aislado dentro de tu ordenador. Copia directamente los archivos compilados a un almacén central local y desde ahí los inyecta en la aplicación consumidora como si provuieran de una instalación real de npm.

Paso 1: Instalación global

npm install -g yalc

Paso 2: Publicar cambios desde la librería

En la carpeta de tu librería, publica el paquete en el almacén local:

yalc publish

Si vas a realizar modificaciones constantes, puedes usar yalc push. Este comando compila, actualiza el almacén local e inyecta inmediatamente la nueva versión en todas las aplicaciones consumidoras que la estén utilizando:

yalc push

Paso 3: Consumir el paquete local

En tu aplicación consumidora, vincula la librería:

yalc add nombre-de-tu-libreria

3. ¿Y si mi librería es un Monorepo?

Si tu proyecto de librería está estructurado como un monorepo (usando npm workspaces, pnpm, Turborepo o Lerna) con múltiples paquetes interconectados, la lógica de vinculación no cambia, pero requiere orden.

Con npm link

Debes enlazar cada paquete que necesites de forma independiente:

# Registrar desde la raíz con npm workspaces (npm v7+)
npm link -w packages/paquete-a -w packages/paquete-b

# Enlazar en la app consumidora
npm link paquete-a paquete-b

Con yalc

Es la opción recomendada para monorepos, ya que no rompe las referencias cruzadas internas entre paquetes:

  1. Entra a cada paquete modificado del monorepo y ejecuta yalc publish (o automatiza el proceso con un script global).
  2. En la app consumidora, añade los paquetes necesarios:
  3. Ejecuta el comando
yalc add paquete-a paquete-b

Si tengo varios packages y quiero publicarlos todos de una vez

Hacer el yalc add paquete-a paquete-b si tienes que publicar varios packages de un monorepo no es mucho problema si te creas un script en el package.json.

Ahora bien, en mi caso que uso Lerna en el monorepo de dile-components, tengo un par de scripts que me hacen ese trabajo automáticamente para cada uno de los packages internos.

scripts {
    "yalc:publish:all": "lerna exec --concurrency 1 --stream -- yalc publish",
    "yalc:push:all": "lerna exec --concurrency 1 --stream -- yalc publish --push"
}

Estos scripts sirven para publicar en local todos los paquetes de tu monorepo de forma automatizada y secuencial.

En un monorepo tienes una carpeta raíz y múltiples subcarpetas (paquetes) en su interior (ej. packages/ui, packages/utils, etc.).

Si ejecutaras yalc publish directamente desde la raíz, solo intentarías publicar la raíz de tu proyecto, ignorando las subcarpetas. Lerna actúa como el orquestador: su trabajo con lerna exec es entrar automáticamente carpeta por carpeta a cada uno de los paquetes del monorepo y ejecutar el comando que le indiques (yalc ...) en cada uno de ellos.

--concurrency 1 Obliga a que la ejecución sea estrictamente secuencial (un paquete a la vez, no en paralelo). Esto evita colisiones de archivos o problemas de concurrencia al escribir en el almacén local de yalc. --stream Muestra por consola la salida de texto de cada paquete en tiempo real, prefijando cada línea con el nombre del paquete para que sepa exactamente qué paquete se está procesando.

El segundo script (yalc:push:all) es el que uso en el día a día para que, tras compilar el monorepo, los cambios se propaguen automáticamente a tu app consumidora sin tocar nada más. El comando yalc push funciona tanto si usaste yalc add como si usaste yalc link en la aplicación consumidora.

4. Gestión con Git: Cómo evitar romper el repositorio remoto

Aquí está la desventaja de este flujo y la precaución que debes tener...

Uno de los errores más comunes al trabajar con herramientas de desarrollo local es subir por accidente referencias locales a Git. Si comiteas un package.json modificado por yalc add, tus compañeros de equipo o el servidor de CI/CD fallarán al intentar compilar o desplegarse en remoto.

Para trabajar de forma segura, sigue estas reglas:

Regla 1: Protege tu .gitignore

Añade las siguientes líneas al .gitignore de tu aplicación consumidora:

.yalc
yalc.lock

Regla 2: Usa yalc link en lugar de yalc add

yalc add modifica tu package.json incluyendo una dependencia tipo "file:.yalc/...".

Si en su lugar usas:

yalc link nombre-de-tu-libreria

yalc inyectará los archivos directamente en la carpeta node_modules **sin tocar tu package.json**. De este modo, aunque olvides limpiar tu entorno antes de hacer commit, tu control de versiones se mantendrá intacto.

Regla 3: Limpieza antes de hacer Commit (Si usaste yalc add)

Si optaste por yalc add, debes restaurar el proyecto a su estado original antes de enviar tus cambios al repositorio remoto:

# 1. Elimina la referencia local de Yalc
yalc remove nombre-de-tu-libreria

# 2. Reinstala la dependencia oficial desde npm
npm install

Resumen: ¿Qué técnica deberías utilizar?

Adoptar este flujo local te ahorrará horas de compilaciones innecesarias y mantendrá tu registro de npm limpio de versiones de prueba que no deberías subir.

Miguel Angel Alvarez

Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...

Manual