如何覆盖嵌套的NPM依赖版本?

我想使用grunt-contrib-jasmine NPM包。它有各种依赖关系。依赖关系图的一部分是这样的:

─┬ grunt-contrib-jasmine@0.4.1
│ ├─┬ grunt-lib-phantomjs@0.2.0
│ │ ├─┬ phantomjs@1.8.2-2

不幸的是,这个版本phantomjs有一个错误,阻止它在Mac OS x上正确安装。这在最新版本中得到了修复。

如何让grunt-lib-phantomjs使用phantomjs的新版本?

一些附加上下文:

325113 次浏览

您可以使用npm收缩包装功能,以覆盖任何依赖项或子依赖项。

我刚刚在我们的grunt项目中做到了这一点。我们需要一个更新版本的connect,因为2.7.3。给我们带来了麻烦。所以我创建了一个名为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应该在为项目安装时自动拾取它。

(参见:# EYZ0)

# EYZ1。# EYZ2

例如,项目有typescript版本4.6.2作为直接开发依赖,而awesome-typescript-loader使用typescript的旧版本2.7。下面是如何告诉npmtypescript4.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"
}
}
}

如果你不使用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"
}
}
}

使用最新版本的依赖项:

{
"name": "myproject",
"version": "0.0.0",
"scripts": ...
"dependencies": ...
"devDependencies": {
"awesome-typescript-loader": "^5.2.1",
...
},
"overrides": {
"awesome-typescript-loader": {
"typescript": "latest"
}
}
}

同样的overrides可以用于dependenciesdevDependencies


如果你使用的是npm版本>5 but <8.3.0:编辑你的package-lock.json:从"requires"部分移除这个库,并将它添加到"dependencies"下。

例如,您希望deglob包使用glob包版本3.2.11而不是当前版本。你打开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"
}
},

"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"
}
}
},

现在删除你的node_modules文件夹,运行npm ci(或旧版本的node/npm的npm install),它将添加缺少的部分到"dependencies"部分。


对于使用纱线的人。

我尝试使用npm收缩膜,直到我发现纱线cli忽略了我的npm收缩膜。json文件。

Yarn有https://yarnpkg.com/lang/en/docs/selective-version-resolutions/。整洁。

看看这个答案:https://stackoverflow.com/a/41082766/3051080

我有一个问题,其中一个嵌套依赖项有npm审计漏洞,但我仍然想维护父依赖项版本。npm的收缩膜解决方案不适合我,所以我所做的是覆盖嵌套的依赖版本:

  1. 删除package-lock.json中'requires'部分下的嵌套依赖项
  2. 在包的DevDependencies下添加更新的依赖项。Json,这样需要它的模块仍然能够访问它。
  3. npm我

唯一适合我的解决方案(节点12。npm 6.x)使用了@Rogerio查维斯开发的npm-force-resolutions

首先,通过以下方法安装:

npm install npm-force-resolutions --save-dev

如果某些损坏的传递依赖脚本阻止您安装任何东西,您可以添加--ignore-scripts

然后在package.json中定义应该覆盖的依赖项(你必须设置确切版本号):

"resolutions": {
"your-dependency-name": "1.23.4"
}

"scripts"部分添加新的preinstall条目:

"preinstall": "npm-force-resolutions",

现在,npm install将应用更改,并强制your-dependency-name在所有依赖项的版本1.23.4

@user11153的答案在本地为我工作,但当试图做一个干净的安装(也就是删除node_modules),我会得到:

npm-force-resolutions: command not found

我必须更新preinstall脚本为:

"preinstall": "npm i npm-force-resolutions && npm-force-resolutions"

它确保在尝试运行npm-force-resolutions包之前已经安装了它。

也就是说,如果你可以用纱线代替,我会这样做,然后使用@Gus的答案。

我本来打算走npm-force-resolutions的路线,但似乎只要在我自己的package.json中包含依赖就可以解决这个问题。

我相信这在我的案例中是有效的,因为原始依赖项允许我想要更新的依赖项的补丁版本。因此,通过手动包含一个新版本,它仍然满足原始依赖项的依赖,并将使用我手动添加的依赖项。

例子

问题

我需要更新plyr到版本3.6.93.6.8

我的

# EYZ0

{
"dependencies": {
"react-plyr": "^3.2.0"
}
}

反应Plyr

# EYZ0

{
"dependencies": {
"plyr": "^3.6.8"
}
}

注意,对于plyr依赖,它以^开始,这意味着它可以接受任何小补丁。你可以在这里了解更多:

https://docs.npmjs.com/about-semantic-versioning#using-semantic-versioning-to-specify-update-types-your-package-can-accept

更新我的

这将从我的package.json更新plyr依赖项。

# EYZ0

{
"dependencies": {
"plyr": "^3.6.9",
"react-plyr": "^3.2.0"
}
}

对于NPM v8.3,正确的处理方法是通过package.json文件的overrides部分。

如果您需要对您的依赖项进行特定的更改 依赖项,例如将依赖项的版本替换为 已知的安全问题,用fork替换现有的依赖项,或者 确保在所有地方都使用相同版本的包,

覆盖提供了一种在依赖树中替换包的方法 用另一个版本,或者完全用另一个包。这些改变可以

.

.

确保foo包总是作为1.0.0版本安装 不管你的依赖依赖于哪个版本:

{
"overrides": {
"foo": "1.0.0"
}
}

还有其他各种更细致的配置,允许您仅在某个包是特定包层次结构的依赖项时覆盖该包。有关更多详细信息,请查看https://docs.npmjs.com/cli/v8/configuring-npm/package-json#overrides

先运行这个

npm i -D @types/eslint@8.4.3

这将解决问题

基于其余的答案,我提供了相同的解决方案,但是我显示了包。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"
}
}

2022年11月"loader-utils"安全漏洞,它被要求

  • 如果您在2中,请使用2.0.4版本。X
  • 如果您是3版本,请使用3.2.1版本。X

为了验证

  • 添加包。Json覆盖标签
  • 删除package-lock.json
  • 运行“npm install”;
  • 运行“npm audit”;