我想使用“咕哝-贡献-茉莉花”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?

一些附加上下文:

Grunt-contrib-jasmine明确要求版本为“~0.2.0”的grunt-lib-phantomjs,它明确要求版本为“~1.8.1”的phantomjs。 首先将phantomjs添加到包的依赖项中没有效果;两个版本都安装了,而unt-contrib-jasmine仍然使用旧版本(参见:当使用NPM安装一个包时,你可以告诉它使用一个依赖项的不同版本吗?)


当前回答

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

其他回答

你可以使用npm shrinkwrap功能,以覆盖任何依赖项或子依赖项。

我刚在我们的一个小项目里做过这个。从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/)

用完全不同的包进行嵌套替换

如果你只是对覆盖包的版本号感兴趣,其他答案中列出的大多数策略都很有效,但在我们的例子中,我们需要找到一种方法,用不同的包覆盖嵌套的npm子依赖项。关于你为什么想要这样做的详细信息,请参考以下问题:

如何重写一个嵌套的npm子依赖与完全不同的包(不仅仅是不同的包版本号)?

直接指定tarball

对于使用其他人提到的npm-force-resolutions策略将一个包嵌套替换为一个完全不同的包,您只需要提供一个指向tarball的链接,通常在该链接中指定覆盖版本号。

以替换易受攻击的包ansi-html为例,使用此包的固定分支ansi-html-community,即包的决议部分。Json应该是这样的:

"resolutions": {
    "ansi-html": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz"
}

要找到到tarball的链接,使用以下命令,并根据需要修改注册表:

npm view ansi-html-community dist.tarball --registry=https://registry.npmjs.org/

另外,要让npm-force-resolutions在你运行npm install时正常工作,你需要在package.json的scripts部分下有一个preinstall入口:

  "scripts": {
    "preinstall": "npx npm-force-resolutions"
  }

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

npm-force-resolutions: command not found

我必须更新预安装脚本为:

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

这确保在试图运行npm-force-resolutions包之前安装了它。

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

从npm cli v8.3.0(2021-12-09)开始,这个问题可以使用package.json的overrides字段来解决。正如StriplingWarrior的回答所描述的那样

例如,该项目有typescript 4.6.2版本作为直接开发依赖,而awesome-typescript-loader使用旧版本2.7的typescript。下面是如何告诉npm使用awesome-typescript-loader的typescript 4.6.2版本:

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

同样的重写可以用于依赖和devDependencies。


如果你正在使用npm版本>5但<8.3.0:编辑你的包锁。Json:从“要求”部分删除库,并将其添加到“依赖项”下。

例如,您希望deglob包使用glob包3.2.11版本而不是当前版本。你打开包裹锁。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"中删除"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(或npm install旧版本的node/npm),它会将缺失的部分添加到“依赖项”部分。


从NPM v8.3开始,处理这个问题的正确方法是通过包的overrides部分。json文件。

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. Overrides provide a way to replace a package in your dependency tree with another version, or another package entirely. 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: { "overrides": { "foo": "1.0.0" } }

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