¿Cómo anulo las versiones de dependencia de NPM anidadas?
Me gustaría utilizar el grunt-contrib-jasmine
paquete NPM. Tiene varias dependencias. Parte del gráfico de dependencia se ve así:
─┬ grunt-contrib-jasmine@0.4.1
│ ├─┬ grunt-lib-phantomjs@0.2.0
│ │ ├─┬ phantomjs@1.8.2-2
Desafortunadamente, hay un error en esta versión phantomjs
que impide que se instale correctamente en Mac OS X. Esto se solucionó en la última versión.
¿ Cómo puedo grunt-lib-phantomjs
utilizar una versión más reciente de phantomjs
?
Algún contexto adicional:
grunt-contrib-jasmine
requiere explícitamente la versión"~0.2.0"
degrunt-lib-phantomjs
, que requiere explícitamente la versión"~1.8.1"
dephantomjs
.- Agregar
phantomjs
primero las dependencias de mi paquete no tiene ningún efecto; ambas versiones están instaladas ygrunt-contrib-jasmine
todavía usan las versiones anteriores (consulte: Al instalar un paquete con NPM, ¿puede indicarle que use una versión diferente de una de sus dependencias? ).
A partir de npm cli v8.3.0 (09/12/2021), esto se puede resolver utilizando el overrides
campo package.json . Como se describe en la respuesta de StriplingWarrior
Por ejemplo, el proyecto tiene typescript
una versión 4.6.2
como dependencia directaawesome-typescript-loader
de desarrollo y utiliza una versión anterior 2.7
de typescript
. Así es como puedes saber npm
si usar la versión 4.6.2
de typescript
for awesome-typescript-loader
:
{
"name": "myproject",
"version": "0.0.0",
"scripts": ...
"dependencies": ...
"devDependencies": {
"typescript": "~4.6.2",
"awesome-typescript-loader": "^5.2.1",
...
},
"overrides": {
"awesome-typescript-loader": {
"typescript": "$typescript"
}
}
}
Si no lo utiliza typescript
como dependencia de desarrollo directa , debe escribir 4.6.2
en lugar de $typescript
en la overrides
sección:
{
"name": "myproject",
"version": "0.0.0",
"scripts": ...
"dependencies": ...
"devDependencies": {
"awesome-typescript-loader": "^5.2.1",
...
},
"overrides": {
"awesome-typescript-loader": {
"typescript": "~4.6.2"
}
}
}
Para usar la última versión de la dependencia:
{
"name": "myproject",
"version": "0.0.0",
"scripts": ...
"dependencies": ...
"devDependencies": {
"awesome-typescript-loader": "^5.2.1",
...
},
"overrides": {
"awesome-typescript-loader": {
"typescript": "latest"
}
}
}
Lo mismo overrides
se puede utilizar para ambos dependencies
y devDependencies
.
Si está utilizando la versión npm >5 pero <8.3.0: edite su package-lock.json
: elimine la biblioteca de "requires"
la sección y agréguela en "dependencias".
Por ejemplo, desea que deglob
el paquete utilice glob
la versión del paquete 3.2.11
en lugar de la actual. Abres package-lock.json
y ves:
"deglob": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/deglob/-/deglob-2.1.0.tgz",
"integrity": "sha1-TUSr4W7zLHebSXK9FBqAMlApoUo=",
"requires": {
"find-root": "1.1.0",
"glob": "7.1.2",
"ignore": "3.3.5",
"pkg-config": "1.1.1",
"run-parallel": "1.1.6",
"uniq": "1.0.1"
}
},
Quitar "glob": "7.1.2",
de "requires"
, agregar "dependencies"
con la versión adecuada:
"deglob": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/deglob/-/deglob-2.1.0.tgz",
"integrity": "sha1-TUSr4W7zLHebSXK9FBqAMlApoUo=",
"requires": {
"find-root": "1.1.0",
"ignore": "3.3.5",
"pkg-config": "1.1.1",
"run-parallel": "1.1.6",
"uniq": "1.0.1"
},
"dependencies": {
"glob": {
"version": "3.2.11"
}
}
},
Ahora elimine su node_modules
carpeta, ejecútela npm ci
(o npm install
para la versión anterior de node/npm) y agregará las partes faltantes a la "dependencies"
sección.
Puede utilizar la funcionalidad npm encogimiento para anular cualquier dependencia o subdependencia.
Acabo de hacer esto en un grunt
proyecto nuestro. Necesitábamos una versión más nueva de connect, ya que 2.7.3
. nos estaba causando problemas. Entonces creé un archivo llamado npm-shrinkwrap.json
:
{
"dependencies": {
"grunt-contrib-connect": {
"version": "0.3.0",
"from": "[email protected]",
"dependencies": {
"connect": {
"version": "2.8.1",
"from": "connect@~2.7.3"
}
}
}
}
}
npm
debería recogerlo automáticamente mientras realiza la instalación del proyecto.
(Ver: https://nodejs.org/en/blog/npm/managing-node-js-dependencies-with-shrinkwrap/ )
A partir de npm v8.3 (lanzado con Node.js 16 ), la forma correcta de solucionar esto es a través de la overrides
sección de su package.json
archivo.
Si necesita realizar cambios específicos en las dependencias de sus dependencias, por ejemplo, reemplazar la versión de una dependencia con un problema de seguridad conocido, reemplazar una dependencia existente con una bifurcación o asegurarse de que se use la misma versión de un paquete en todas partes, entonces puede agregar una anulación.
Las anulaciones proporcionan una manera de reemplazar un paquete en su árbol de dependencias con otra versión o con otro paquete completo. Estos cambios pueden tener un alcance tan específico o vago como se desee.
Para asegurarse de que el paquete foo siempre esté instalado como versión 1.0.0 sin importar en qué versión dependan sus dependencias:
{ "overrides": { "foo": "1.0.0" } }
Hay una variedad de otras configuraciones más matizadas que le permiten anular un paquete solo cuando depende de una jerarquía de paquetes particular. Para obtener más detalles, consulte https://docs.npmjs.com/cli/v9/configuring-npm/package-json#overrides
La única solución que funcionó para mí (nodo 12.x, npm 6.x) fue usar npm-force-solving desarrollado por @Rogerio Chaves .
Primero, instálelo mediante:
npm install npm-force-resolutions --save-dev
Puede agregar --ignore-scripts
si algunos scripts de dependencia transitiva rotos le impiden instalar algo.
Luego, package.json
defina qué dependencia se debe anular (debe establecer el número de versión exacto ):
"resolutions": {
"your-dependency-name": "1.23.4"
}
y en "scripts"
la sección agregue una nueva entrada de preinstalación:
"preinstall": "npm-force-resolutions",
Ahora, npm install
aplicará cambios y forzará your-dependency-name
la versión 1.23.4
para todas las dependencias.