Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

175
Vistas
¿Cómo podemos evitar con seguridad los conflictos entre un paquete npm local y uno global para las herramientas de línea de comandos, que llaman al archivo de destino mediante require()?

Conflictos de una instalación global y local

Estoy trabajando en la herramienta de línea de comandos npm y el paquete https://github.com/ecma-make/ecmake . Me encontré con un extraño conflicto entre una versión del paquete instalada globalmente y localmente.

Puedo evitar este conflicto vinculando uno contra la biblioteca del otro. Entonces solo hay una instancia de la biblioteca y no hay conflicto. Ahora tengo que pensar en el usuario, que instala el paquete en ambos lugares, una vez globalmente para poder ejecutar el comando sin el prefijo npx , una vez localmente para que la biblioteca aparezca en la sección de desarrollo de package.json .

como reproducir

 # prepare test fixture mkdir ecmakeTest cd ecmakeTest/ npm init -y # install globally npm install -g @ecmake/ecmake@0.3.1 npm ls -g @ecmake/ecmake # install locally npm install --save-dev @ecmake/ecmake@0.3.1 npm ls @ecmake/ecmake # init ecmakeCode.js npx ecmake --init # run with local lib => shows the expected behaviour npx ecmake all # run with global lib => NoRootTaskError ecmake all

Origen del conflicto

El seguimiento de la pila nos guía a la línea dentro de la instalación global: /usr/local/lib/node_modules/@ecmake/ecmake/lib/runner/reader.js:21:13 .

 if (!(root instanceof Task)) { throw new Reader.NoRootTaskError(this.makefile); }

¿Que paso?

La root del objeto creada con la biblioteca local se comparó con la definición de clase de la biblioteca global. Tienen el mismo código pero son copias diferentes del mismo código.

El ecmake runner global requiere el archivo MAKE local ecmakeCode.js . Este archivo, a su vez, requiere la definición de Task de la biblioteca local.

 const root = module.exports = require('@ecmake/ecmake').makeRoot(); root.default .described('defaults to all') .awaits(root.all); [...]

Podemos verificar que en realidad ambas bibliotecas han sido llamadas poniendo una instrucción de registro en ambas.

¿Cómo resuelven esto los demás?

Gulp y Grunt exportan una función que toma la dependencia real por inyección. Mientras que la inyección de dependencia es generalmente muy inteligente, en este caso no es tan bonita. Todo el archivo se envuelve. Me gustaría evitar esta función de ajuste.

Consulte: https://gulpjs.com/docs/en/getting-started/quick-start#create-a-gulpfile

Ver: https://gruntjs.com/getting-started

Lo que ya consideré

El corredor podría verificar primero, si existe tal conflicto. En caso de que pueda delegar los argumentos dados a ecmake global a npx ecmake local ejecutando un proceso secundario.

Por desgracia, esto retrasaría al corredor. Se requiere al menos un subproceso, tal vez más para verificar la situación.

La pregunta

¿Tiene una solución general para abordar este desafío (aparte de las que ya nombré con sus desventajas)?

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

Como primera parte de mi propia respuesta, investigo por qué es poco probable una solución canónica. Después de la fecha límite de la recompensa, agregaré algunas estrategias para encontrar una solución.

Sin solución canónica

El archivo MAKE crea un modelo de datos. El corredor carga e inspecciona este modelo de datos y ejecuta las instrucciones almacenadas en él. Tanto el corredor como el modelo de datos necesitan una biblioteca. Hay una instalación global de npm y otra local . Esto ya da cuatro combinaciones posibles.

El corredor ecmake proporciona una opción --base directory modelada make partir de la herramienta de creación original. El significado es "cambiar al directorio nombrado antes de hacer nada". Esto le da un segundo lugar a una biblioteca local. Estamos en tres por tres combinaciones.

Voy a nombrar varias estrategias de solución. Combinando todo esto, hay decenas de opciones más o menos razonables. Esto hace que una respuesta canónica sea poco probable. No obstante, los desafíos fundamentales de este ejemplo generalmente se aplican a muchas herramientas de línea de comandos.

respuestas exactas

Las respuestas que abordan con precisión las preguntas originales son aquellas estrategias, que desacoplan el modelo y el corredor o que tengan cuidado, que solo se llame a una instancia de la biblioteca.

Restricciones adicionales

La vida real no responde a las preguntas exactamente. En el caso de ecmake la búsqueda de soluciones planteó limitaciones adicionales. Quiero asegurarme de que las versiones del modelo y el corredor coincidan con la versión principal, contra la cual se codificó el archivo MAKE . Los conflictos de versión en los cambios de versión importantes deben evitarse de antemano.

Por lo tanto, el archivo MAKE debe incluirse con la versión adecuada en package.json . Si solo hay una instalación global, debería intentar ejecutarse, pero se debería dar una advertencia de que falta una instalación local.

Soluciones

Para venir después de la fecha límite de la recompensa.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda