Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

168
Views
¿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 answers
Answer question

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!