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


289

我想使用grunt-contrib-jasmineNPM软件包。它具有各种依赖性。依赖图的一部分如下所示:

─┬ 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

一些其他上下文:


只需git clone或分叉所需的模块。您也可以phantomjs手动删除嵌套。
Aleksei Zabrodskii

3
grunt-contrib-jasmine是在0.5.1上,它使用grunt-lib-phantomjs@0.3.1,它使用phantomjs@1.9.1-0:)
gustavohenke

Answers:


238

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

我刚刚在我们的一个艰苦的项目中做到了这一点。从2.7.3开始,我们需要更新版本的connect。给我们带来麻烦 所以我创建了一个名为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应该会自动将其拾取。

(请参阅:https : //nodejs.org/en/blog/npm/managing-node-js-dependencies-with-shrinkwrap/


7
当我这样做时,仅grunt-contrib-connect安装依赖项及其子项。我在package.json中的所有其他依赖项均未安装。
iDVB 2015年

5
我和@iDVB有相同的问题。我最终编辑了node_modules目录,以便完整的收缩包装依赖项转储正是我想要的,而不仅仅是覆盖。但是仍然是一种痛苦的解决方案。
Kobold 2015年

2
@Domi这个文件是通过运行npmrinkwrap创建的,条目不是手工添加的
glasspill 2015年

13
不幸的是,正如该错误中提到的那样,使用npm4时,简约方法不再起作用。(删除时node_modules,使用最小的收缩包装运行安装似乎会devDependencies保持原样,尽管忽略dependencies,但是运行另一次安装会删除非显式项,因此,现在重要的是运行npm shrinkwrap以获取完整文件,修改有问题的部分,以及然后npm install再次运行)
Brett Zamir

6
npm 6.4只会覆盖收缩包装文件并使用过时的依赖项
ShadSterling,

82

对于2018年及以后的版本,请使用npm 5或更高版本:编辑您的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"
  }
},

"glob": "7.1.2",从中删除"requires",并添加"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 install,它将向该"dependencies"部分添加缺少的部分。


4
只要npm install运行一次就可以了。在我的情况下,必须进行编辑,因为嵌套的dep会导致失败。
ppasler '18

59
这将被删除,任何时候你运行npm i编辑包lock.json并增加孩子的依赖性为“依赖性”那里,加上孩子依赖于你的package.json“依赖关系”部分,而不是
trickpatty

6
我创建了一个自动为您执行此操作的库:github.com/rogeriochaves/npm-force-resolutions
Rogerio Chaves

14
它可以工作,但是如果我npm install再次运行,则所有更改都package-lock.json将还原,并且我得到了坏版本的dep。
2rs2ts

14
我跑步npm ci,这并不触及package-lock.json
sschoof


0

我遇到一个问题,其中一个嵌套依赖项具有一个npm审核漏洞,但是我仍然想维护父依赖项版本。npm收缩包装解决方案对我不起作用,所以我做了什么来覆盖嵌套的依赖版本:

  1. 删除package-lock.json中'requires'部分下的嵌套依赖关系
  2. 在package.json的DevDependencies下添加更新后的依赖项,以便需要它的模块仍然可以访问它。

-1

NPM收缩包装提供了一个很好的解决方案。它允许我们重写特定子模块的特定依赖项的版本。

本质上,当您运行npm install时,npm首先会在您的根目录中查找是否存在npm-shrinkwrap.json文件。如果是这样,它将首先使用它来确定软件包的依赖关系,然后返回到处理package.json文件的正常过程。

要创建npm-shrinkwrap.json,您需要做的就是

 npm shrinkwrap --dev

码:

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

3
这与当前接受的答案不同吗?该答案有两个反对意见,表明较新版本的npm要么需要其他手动步骤,要么对此解决方案做不受欢迎的事情。不是吗?
法比奥·贝尔特拉米尼

-1

我找到了对我有用的解决方案。

所以。首先按照所有其他建议的解决方案编辑npm-shrinkwrap.json文件。

然后,(在Windows上):

  • 右键单击“ npm-shrinkwrap.json”文件
  • 物产
  • 在属性下,选择“只读”。 这将阻止npm修改mpn-shrinkwrap.json文件。

如果您仅执行一次“ npm install”操作,那么其他建议的解决方案就足够了。但是,在第一次“ npm安装”之后,文件“ npm-shrinkwrap.json”会像修改之前一样再次被修改。


-1:这将要求您每次要进行更改时再次解锁文件。在这种情况下,无论如何,您都将手动编辑丢失到收缩包装文件。另外,任何与您的代码协作的人也需要启用此黑客。
thomaux
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.