如何用不同的包完全覆盖嵌套的 npm 子依赖项(不仅仅是不同的包版本号)?

Posted

技术标签:

【中文标题】如何用不同的包完全覆盖嵌套的 npm 子依赖项(不仅仅是不同的包版本号)?【英文标题】:How to override a nested npm sub-dependency with a different package altogether (not just different package version number)? 【发布时间】:2021-12-01 12:18:15 【问题描述】:

概述

我在解决 npm audit 识别的 ReDoS 漏洞时遇到问题。我的应用程序有一个嵌套的子依赖 ansi-html 容易受到攻击,但不幸的是,似乎 maintainers have gone AWOL.正如您在 Github 问题的 cmets 部分看到的那样,为了解决这个问题,社区已经创建了一个名为 ansi-html-community 的 repo 的分支,位于 here,它解决了这个漏洞。

因此,我想用ansi-html-community 替换所有ansi-html 的嵌套引用。

问题

我使用npm-force-resolutions 的正常策略似乎无法完全覆盖具有不同包的嵌套子依赖项,而只能覆盖具有不同版本号的相同包。我已经研究了几个小时,但不幸的是,这是我找到解决此问题的唯一方法would appear to be with yarn,我现在正在认真考虑使用它来代替 npm。但是,这并不理想,因为我们的整个 CI/CD 管道都配置为使用 npm。

有没有人知道任何其他方式来完成嵌套的子依赖包替换/解析而不必切换到使用纱线?

相关问题

这些是我能够找到的感兴趣的问题,但不幸的是,它们往往只讨论覆盖包版本号的方法,而不是包本身。

讨论如何覆盖版本号:

How do I override nested NPM dependency versions?

npm shrinkwrap有评论讨论(不理想):

npm - how to override a dependent package's dependencies?

其他相关的 *** 问题:

CSE Index of related questions

【问题讨论】:

【参考方案1】:

我想通了。截至 2021 年 10 月,使用 npm-force-resolutions 的解决方案实际上与使用 yarn 指定它的方式非常相似。您只需要提供指向通常指定覆盖版本号的 tarball 的链接。 package.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 install 时使 npm-force-resolutions 正常工作,您需要在 package.jsonscripts 部分下添加一个 preinstall 条目:

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

【讨论】:

这似乎对我不起作用。 npm ls ansi-html 仍然返回常规的 ansi-html@0.0.7 版本。你只使用标准的预安装脚本吗? 这并不一定意味着它不起作用。只要您的ansi-html 最终解决为ansi-html-community,您就应该很好。如果您还没有尝试删除您的 package-lock.json 并重新生成它。然后搜索 ansi-html 的实例并验证它正在解析到什么。 preinstall script 运行npm-force-resolutions(通过***.com/a/68095189/132735)没有产生期待的结果(将tarball 作为resolved入口)。改为手动运行它 (npx npm-force-resolutions),然后,当然,推动 lockfile 就可以了。或者,可以转移到存在原生选择性分辨率支持的最新纱线。显然 npm 也在做一个 overrides 功能 -- github.com/npm/rfcs/blob/main/accepted/0036-overrides.md :> 但是node_module里面没有安装需要的包。它只更新 package-lock.json 文件。 两者都可以。这个想法是,一旦您处于 CI 环境中,您就可以简单地使用 npm ci,此时 node_modules 将直接从您的 package-lock.json 生成(仅此而已)。但是,当您在本地运行 npm install 时,它将同时更新您的 node_modulespackage-lock.json(假设您已在 scripts 部分中设置了 preinstall package.json,如末尾所示我的帖子)。如果由于某种原因您没有发生这种情况,请考虑先完全删除您的 node_modulespackage-lock.json,然后再试一次。【参考方案2】:

对于那些需要与 yarn 相同的解决方案的人,只需将其添加到您的 package.json 中

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

然后运行yarn install

你也可以在这之后再做,如果它不能立即起作用

rm yarn.lock

yarn import

【讨论】:

以上是关于如何用不同的包完全覆盖嵌套的 npm 子依赖项(不仅仅是不同的包版本号)?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 `yarn` 覆盖嵌套依赖项?

npm - 将安装的包保存为依赖项

如何识别哪些 npm 包只是对等依赖项?

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

如何强制排除 NPM 的嵌套依赖项?

如何强制 npm 3 安装嵌套依赖项?