[英]How do I override nested NPM dependency versions?
I would like to use the grunt-contrib-jasmine
NPM package. It has various dependencies.我想使用
grunt-contrib-jasmine
NPM package。它有各种依赖项。 Part of the dependency graph looks like this:部分依赖图如下所示:
─┬ grunt-contrib-jasmine@0.4.1
│ ├─┬ grunt-lib-phantomjs@0.2.0
│ │ ├─┬ phantomjs@1.8.2-2
Unfortunately, there's a bug in this version phantomjs
which prevents it from installing correctly on Mac OS X. This is fixed in the latest version.不幸的是,这个版本的
phantomjs
中有一个错误,导致它无法在 Mac OS X 上正确安装。这在最新版本中已修复。
How can I get grunt-lib-phantomjs
to use a newer version of phantomjs
?我怎样才能让
grunt-lib-phantomjs
使用更新版本的phantomjs
?
Some additional context:一些额外的背景:
grunt-contrib-jasmine
explicitly requires version "~0.2.0"
of grunt-lib-phantomjs
, which explicitly requires version "~1.8.1"
of phantomjs
. grunt-contrib-jasmine
明确要求grunt-lib-phantomjs
的版本"~0.2.0"
,它明确要求phantomjs
的版本"~1.8.1"
。phantomjs
to my package's dependencies first has no effect;phantomjs
添加到我的包的依赖项中没有任何效果; both versions are installed and grunt-contrib-jasmine
still uses the older versions (see: When installing a package with NPM, can you tell it to use a different version of one of its dependencies? ).grunt-contrib-jasmine
仍然使用旧版本(参见: When installing a package with NPM, can you tell it to use a different version of its one of its dependencies? )。 You can use npm shrinkwrap functionality, in order to override any dependency or sub-dependency.您可以使用npm 收缩包装功能,以覆盖任何依赖或子依赖。
I've just done this in a grunt
project of ours.我刚刚在我们的一个
grunt
的项目中做到了这一点。 We needed a newer version of connect, since 2.7.3
.从
2.7.3
开始,我们需要更新版本的连接。 was causing trouble for us.给我们带来了麻烦。 So I created a file named
npm-shrinkwrap.json
:所以我创建了一个名为
npm-shrinkwrap.json
的文件:
{
"dependencies": {
"grunt-contrib-connect": {
"version": "0.3.0",
"from": "grunt-contrib-connect@0.3.0",
"dependencies": {
"connect": {
"version": "2.8.1",
"from": "connect@~2.7.3"
}
}
}
}
}
npm
should automatically pick it up while doing the install for the project. npm
应该在为项目安装时自动选择它。
(See: https://nodejs.org/en/blog/npm/managing-node-js-dependencies-with-shrinkwrap/ ) (见: https://nodejs.org/en/blog/npm/managing-node-js-dependencies-with-shrinkwrap/ )
As of npm cli v8.3.0 (2021-12-09) this can be solved using the overrides
field of package.json .从 npm cli v8.3.0 (2021-12-09) 开始,这可以使用 package.json 的
overrides
字段来解决。 As described in StriplingWarrior's answer如StriplingWarrior 的回答中所述
For example, the project has typescript
version 4.6.2
as direct development dependency and awesome-typescript-loader
that uses old version 2.7
of typescript
.例如,该项目具有
typescript
版本4.6.2
作为直接开发依赖项和使用旧版本2.7
typescript
awesome-typescript-loader
。 Here is how you can tell npm
to use version 4.6.2
of typescript
for awesome-typescript-loader
:以下是如何告诉
npm
使用typescript
的4.6.2
版本来执行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"
}
}
}
If you don't use typescript
as direct development dependency, then you have to write 4.6.2
instead of $typescript
in overrides
section:如果您不使用
typescript
作为直接开发依赖项,那么您必须在overrides
部分编写4.6.2
而不是$typescript
:
{
"name": "myproject",
"version": "0.0.0",
"scripts": ...
"dependencies": ...
"devDependencies": {
"awesome-typescript-loader": "^5.2.1",
...
},
"overrides": {
"awesome-typescript-loader": {
"typescript": "~4.6.2"
}
}
}
Same overrides
can be used for both dependencies
and devDependencies
. dependencies
项和devDependencies
都可以使用相同的overrides
。
If you're using npm version >5 but <8.3.0: edit your package-lock.json
: remove the library from "requires"
section and add it under "dependencies".如果您使用 npm 版本 >5 但 <8.3.0:编辑您的
package-lock.json
:从"requires"
部分删除库并将其添加到“依赖项”下。
For example, you want deglob
package to use glob
package version 3.2.11
instead of its current one.例如,您希望
deglob
package 使用glob
package 版本3.2.11
而不是当前版本。 You open package-lock.json
and see:打开
package-lock.json
并查看:
"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"
}
},
Remove "glob": "7.1.2",
from "requires"
, add "dependencies"
with proper version:从
"requires"
中删除"glob": "7.1.2",
,添加具有正确版本的"dependencies"
:
"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"
}
}
},
Now remove your node_modules
folder, run npm ci
(or npm install
for old version of node/npm) and it will add missing parts to the "dependencies"
section.现在删除你的
node_modules
文件夹,运行npm ci
(或npm install
for old version of node/npm),它会将缺失的部分添加到"dependencies"
部分。
As of NPM v8.3 , the correct way to deal with this is via the overrides
section of your package.json
file.从 NPM v8.3开始,处理此问题的正确方法是通过
package.json
文件的overrides
部分。
If you need to make specific changes to dependencies of your dependencies, for example replacing the version of a dependency with a known security issue, replacing an existing dependency with a fork, or making sure that the same version of a package is used everywhere, then you may add an override.
如果您需要对依赖项的依赖项进行特定更改,例如用已知安全问题替换依赖项的版本,用分叉替换现有依赖项,或者确保在任何地方都使用相同版本的 package,那么你可以添加一个覆盖。
Overrides provide a way to replace a package in your dependency tree with another version, or another package entirely.
覆盖提供了一种将依赖关系树中的 package 替换为另一个版本或完全替换为另一个 package 的方法。 These changes can be scoped as specific or as vague as desired.
这些更改的范围可以根据需要具体或模糊。
To make sure the package foo is always installed as version 1.0.0 no matter what version your dependencies rely on:
为了确保 package foo 始终安装为 1.0.0 版本,无论您的依赖项依赖什么版本:
{ "overrides": { "foo": "1.0.0" } }
There are a variety of other, more nuanced configurations allowing you to only override a package when it's a dependency of a particular package hierarchy.还有许多其他更细微的配置,允许您仅在 package 层次结构的依赖项时覆盖 package。 For more details, check out https://docs.npmjs.com/cli/v8/configuring-npm/package-json#overrides
有关更多详细信息,请查看https://docs.npmjs.com/cli/v8/configuring-npm/package-json#overrides
The only solution that worked for me (node 12.x, npm 6.x) was using npm-force-resolutions developed by @Rogerio Chaves .唯一对我有用的解决方案(节点 12.x,npm 6.x)是使用由@Rogerio Chaves开发的npm-force-resolutions 。
First, install it by:首先,通过以下方式安装它:
npm install npm-force-resolutions --save-dev
You can add --ignore-scripts
if some broken transitive dependency scripts are blocking you from installing anything.如果某些损坏的传递依赖脚本阻止您安装任何东西,您可以添加
--ignore-scripts
。
Then in package.json
define what dependency should be overridden (you must set exact version number ):然后在
package.json
中定义应该覆盖的依赖项(您必须设置确切的版本号):
"resolutions": {
"your-dependency-name": "1.23.4"
}
and in "scripts"
section add new preinstall entry:并在
"scripts"
部分添加新的预安装条目:
"preinstall": "npm-force-resolutions",
Now, npm install
will apply changes and force your-dependency-name
to be at version 1.23.4
for all dependencies.现在,
npm install
将应用更改并强制your-dependency-name
为所有依赖项的版本1.23.4
。
For those using yarn.对于那些使用纱线的人。
I tried using npm shrinkwrap until I discovered the yarn cli ignored my npm-shrinkwrap.json file.我尝试使用 npm 收缩包装,直到我发现纱线 cli 忽略了我的 npm-shrinkwrap.json 文件。
Yarn hashttps://yarnpkg.com/lang/en/docs/selective-version-resolutions/ for this.为此,Yarn 有https://yarnpkg.com/lang/en/docs/selective-version-resolutions/ 。 Neat.
整洁的。
Check out this answer too: https://stackoverflow.com/a/41082766/3051080也看看这个答案: https://stackoverflow.com/a/41082766/3051080
Most of the strategies outlined in the other answers here work well if you are just interested in overriding the package's version number, but in our case, we needed to find a way to override a nested npm sub-dependency with a different package altogether.如果您只是对覆盖包的版本号感兴趣,那么此处其他答案中概述的大多数策略都可以很好地工作,但在我们的例子中,我们需要找到一种方法来覆盖嵌套的 npm 子依赖项,并完全使用不同的 package 。 For details on why you would ever want to do this, please refer to the following question:
有关您为什么要这样做的详细信息,请参阅以下问题:
How to override a nested npm sub-dependency with a different package altogether (not just different package version number)? 如何完全覆盖具有不同 package 的嵌套 npm 子依赖项(不仅仅是不同的 package 版本号)?
For nested replacement of a package with an entirely different package using the npm-force-resolutions
strategy that others have mentioned, you just need to provide a link to the tarball where you would normally specify the overriding version number.对于使用其他人提到的
npm-force-resolutions
策略将 package 嵌套替换为完全不同的 package ,您只需提供指向通常指定覆盖版本号的 tarball 的链接。
As an example, for the case of replacing the vulnerable package, ansi-html
, with the fixed fork of this package, ansi-html-community
, your resolutions section of package.json
should look like this: As an example, for the case of replacing the vulnerable package,
ansi-html
, with the fixed fork of this package, ansi-html-community
, your resolutions section of package.json
should look like this:
"resolutions": {
"ansi-html": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz"
}
To find the link to the tarball, use the following command, modifying your registry as necessary:要找到 tarball 的链接,请使用以下命令,根据需要修改您的注册表:
npm view ansi-html-community dist.tarball --registry=https://registry.npmjs.org/
Also, note that for npm-force-resolutions
to work when you run npm install
, you will need a preinstall
entry under the scripts
section of package.json
:另外,请注意,当您运行
npm install
时,要使npm-force-resolutions
起作用,您需要在package.json
的scripts
部分下的preinstall
条目:
"scripts": {
"preinstall": "npx npm-force-resolutions"
}
I had an issue where one of the nested dependency had an npm audit vulnerability, but I still wanted to maintain the parent dependency version.我遇到了一个问题,其中一个嵌套依赖项存在 npm 审计漏洞,但我仍然想维护父依赖项版本。 the npm shrinkwrap solution didn't work for me, so what I did to override the nested dependency version:
npm 收缩包装解决方案对我不起作用,所以我做了什么来覆盖嵌套的依赖版本:
@user11153 's answer worked for me locally, but when trying to do a clean install (aka deleting node_modules
), I would get: @user11153 的答案在本地对我有用,但是在尝试进行全新安装(又名删除
node_modules
)时,我会得到:
npm-force-resolutions: command not found
I had to update the preinstall
script to be:我必须将
preinstall
脚本更新为:
"preinstall": "npm i npm-force-resolutions && npm-force-resolutions"
Which ensures that npm-force-resolutions
package is installed before attempting to run it.这可确保在尝试运行之前安装
npm-force-resolutions
package。
That being said, if you're able to use yarn instead, I would do that and then use @Gus 's answer.话虽这么说,如果您能够改用纱线,我会这样做,然后使用@Gus 的答案。
I was about to go down the npm-force-resolutions
route but it seems that simply including the dependency in my own package.json
fixed the problem for me.我正要在
npm-force-resolutions
路线上进行 go ,但似乎只需将依赖项包含在我自己的package.json
中即可解决我的问题。
I believe this worked in my case because the original dependency allows for patch versions of the dependency in question that I wanted to update.我相信这对我来说是可行的,因为原始依赖项允许我想要更新的相关依赖项的补丁版本。 Thus by manually including a newer version it still fulfilled the dependency of the original dependency and will use the one I've manually added.
因此,通过手动包含一个较新的版本,它仍然满足原始依赖项的依赖项,并将使用我手动添加的那个。
I need to update plyr
to version 3.6.9
from 3.6.8
我需要将
plyr
从3.6.8
更新到版本3.6.9
package.json
{
"dependencies": {
"react-plyr": "^3.2.0"
}
}
package.json
{
"dependencies": {
"plyr": "^3.6.8"
}
}
Notice for the
plyr
dependency it starts with^
this means it can accept any minor patches.注意它以
^
开头的plyr
依赖项,这意味着它可以接受任何小补丁。 You can learn more about that here:您可以在此处了解更多信息:
https://docs.npmjs.com/about-semantic-versioning#using-semantic-versioning-to-specify-update-types-your-package-can-accept
https://docs.npmjs.com/about-semantic-versioning#using-semantic-versioning-to-specify-update-types-your-package-can-accept
This updates the plyr
dependency from my package.json
.这更新了我的
package.json
的plyr
依赖项。
package.json
{
"dependencies": {
"plyr": "^3.6.9",
"react-plyr": "^3.2.0"
}
}
I found a solution that worked for me. 我找到了对我有用的解决方案。
So. 所以。 First edit your npm-shrinkwrap.json file as recommended all others solutions.
首先按照所有其他建议的解决方案编辑npm-shrinkwrap.json文件。
Then, (on Windows): 然后,(在Windows上):
The other proposed solutions are good enough if you are making the 'npm install' operation just once. 如果您仅执行一次“ npm install”操作,那么其他建议的解决方案就足够了。 But after the first 'npm install' the file 'npm-shrinkwrap.json' is modified again as before your modification.
但是,在第一次“ npm安装”之后,文件“ npm-shrinkwrap.json”会像修改之前一样再次被修改。
Based on the rest of the answers, I provide the same solution, but I display the package.json, as I struggled a little bit on where to place the override and how.基于 rest 的答案,我提供了相同的解决方案,但我显示了 package.json,因为我在放置覆盖的位置和方式上有点挣扎。
{
"name": "my-app",
"version": "snapshot",
"scripts": {
"ng": "ng",
"build-dev": "ng build --configuration development",
},
"private": true,
"dependencies": {
"@angular/animations": "~14.2.9",
"@angular/common": "~14.2.9"
...
},
"devDependencies": {
"@angular-devkit/build-angular": "^14.2.8",
....
},
"overrides": {
"loader-utils@>2.0.0 <3": "2.0.4",
"loader-utils@>3.0.0 <4": "3.2.1"
}
}
For November 2022 "loader-utils" security vulnerability, it was requested to针对2022年11月的“loader-utils”安全漏洞,要求
And to verify并验证
I would like to use the grunt-contrib-jasmine
NPM package.我想使用
grunt-contrib-jasmine
NPM软件包。 It has various dependencies.它具有各种依赖性。 Part of the dependency graph looks like this:
依赖关系图的一部分看起来像这样:
─┬ grunt-contrib-jasmine@0.4.1
│ ├─┬ grunt-lib-phantomjs@0.2.0
│ │ ├─┬ phantomjs@1.8.2-2
Unfortunately, there's a bug in this version phantomjs
which prevents it from installing correctly on Mac OS X. This is fixed in the latest version.不幸的是,此版本的
phantomjs
存在一个错误,导致它无法在Mac OS X上正确安装。此问题已在最新版本中修复。
How can I get grunt-lib-phantomjs
to use a newer version of phantomjs
?如何获得
grunt-lib-phantomjs
以使用较新版本的phantomjs
?
Some additional context:一些其他上下文:
grunt-contrib-jasmine
explicitly requires version "~0.2.0"
of grunt-lib-phantomjs
, which explicitly requires version "~1.8.1"
of phantomjs
. grunt-contrib-jasmine
明确要求版本"~0.2.0"
的grunt-lib-phantomjs
,其中明确要求版本"~1.8.1"
的phantomjs
。phantomjs
to my package's dependencies first has no effect;phantomjs
添加到我的程序包的依赖项中没有任何作用。 both versions are installed and grunt-contrib-jasmine
still uses the older versions (see: When installing a package with NPM, can you tell it to use a different version of one of its dependencies? ).grunt-contrib-jasmine
仍使用旧版本(请参阅: 使用NPM安装软件包时,可以告诉它使用其依赖项之一的其他版本吗? )。 Run this first先运行这个
npm i -D @types/eslint@8.4.3
it will solve the issue它将解决问题
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.