ChatGPT解决这个技术问题 Extra ChatGPT

npm 相当于纱线分辨率?

是否有 yarn resolutions 功能的 npm 等效项? npm package.json docs 中没有提及它。

例如,我还想在 3.3.2 中安装 lerna@3.3.2 及其依赖项之一 (@lerna/publish)。目前使用 yarn 这样做,但更喜欢使用 npm 而不是手动更改 package-lock.json 或任何类似的狡猾的东西。

"devDependencies": {
  "lerna": "3.3.2",
},
"resolutions": {
  "@lerna/publish": "3.3.2"
}
你知道 npm shrinkwrap 吗?这可能对你有用。请参阅:docs.npmjs.com/cli/shrinkwrap

J
Julien

npm 本身似乎不支持此功能,但是此软件包旨在添加此功能:

https://github.com/rogeriochaves/npm-force-resolutions


@Gajus:This commit message 建议它现在应该在 npm 7 上运行。npm-force-resolutions 的相应版本是 0.0.10
2022,它受支持stackoverflow.com/a/67397982/1115187
w
walnut_salami

是由于支持 overrides,相当于 yarn 的 resolutions

有关当前 RFC 状态的更多信息:

https://github.com/npm/rfcs/blob/latest/accepted/0036-overrides.md


这似乎适用于 NPM 8.3
2022,它支持开箱即用:stackoverflow.com/a/67397982/1115187
f
fernandopasik

Npm 等效于纱线分辨率是覆盖。在 RFC 被接受之后,现在有一个史诗来观察实施进度。 https://github.com/npm/statusboard/issues/343

编辑:这是在 npm v8.3.0 中发布的

文档:https://docs.npmjs.com/cli/v8/configuring-npm/package-json#overrides

确保软件包 foo 始终安装为版本 1.0.0,无论您的依赖项依赖什么版本:{“overrides”:{“foo”:“1.0.0”}}


G
Gajus

据我所知,npm-force-resolutions 不适用于 v7。 package-lock.json format changed in v7npm-force-resolutions 不再更新相关字段。

然而,编写一个脚本来将你的依赖树限制为只有一个版本的包是相对容易的,例如

#!/usr/bin/env node

/* eslint-disable unicorn/prevent-abbreviations */
/* eslint-disable import/unambiguous */
/* eslint-disable import/no-commonjs */
/* eslint-disable node/shebang */

const fs = require('fs').promises;
const path = require('path');

const main = async (resolutions) => {
  const packageLockFilePath = path.resolve(__dirname, '../package-lock.json');

  for (const [name, version] of Object.entries(resolutions)) {
    const packageLock = JSON.parse(await fs.readFile(packageLockFilePath));

    const packagePaths = Object.keys(packageLock.packages);

    const deletePaths = [];

    for (const packagePath of packagePaths) {
      if (packagePath.endsWith('/' + name)) {
        if (packageLock.packages[packagePath].version !== version) {
          deletePaths.push(packagePath);
        }
      }
    }

    for (const packagePath of deletePaths) {
      for (const deletePath of deletePaths) {
        if (packagePath === deletePath || packagePath.startsWith(deletePath + '/')) {
          // eslint-disable-next-line fp/no-delete
          delete packageLock.packages[packagePath];
        }
      }
    }

    await fs.writeFile(
      packageLockFilePath,
      JSON.stringify(packageLock, null, '  '),
    );
  }
};

main(require('../package.json').resolutions);

此脚本仅删除所有指向不满足 package.json 中定义的 resolutions 的依赖项的链接。

要执行脚本,只需将其添加到 package.json scripts 并定义 resolutions 字段,例如

{
  "scripts": {
    "postinstall": "node bin/fix-package-lock.js"
  },
  "resolutions": {
    "webpack": "5.6.0"
  }
}

resolutions 只是包名称和应该保留在依赖关系树中的那些包的确切版本的映射,即上述配置将删除所有不是 5.6.0 版本。只要您安装 webpack@5.6.0 版本作为您正在使用的项目的依赖项,这将保证所有包都加载相同版本的 webpack。


J
Jeremy

在 package.json 添加类似这样的内容以将任何 grapahql 包(替换为您的问题包)解析为指定版本。

  "resolutions": {
    "graphql": "^15.8.0",
    "**/graphql": "^15.8.0"
  },

您可以列出您使用 npm list <package name> 安装的软件包,以查看需要哪个软件包以及在哪里。未经测试,但认为它在我的机器上工作。


D
Danny North

对于阅读本文的任何人,overrides 现在是自版本 8.3.0 起支持的 npm 功能:party: