等效于纱线分辨率的 npm?

npm是否等同于 纱线分辨率功能? 在 npm package.json 医生中没有提到它。

例如,我想在3.3.2安装 lerna@3.3.2和它的一个依赖项(@lerna/Publishing)。目前用 yarn就是这样做的,但是我们更喜欢使用 npm,而不是手动更改 package-lock.json或者其他类似的东西。

"devDependencies": {
"lerna": "3.3.2",
},
"resolutions": {
"@lerna/publish": "3.3.2"
}
116141 次浏览

Npm 本身似乎并不支持这个功能,但是这个包旨在添加这个功能:

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

是由于支持 overrides,这相当于纱线的 resolutions

有关当前 RFC 状态的详细信息,请参阅:

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

据我所知,npm-force-resolutions不与 v7一起工作。在 v7中改变了 package-lock.json格式npm-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。

等效于纱线分辨率的 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 no 无论依赖于什么版本:

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

对于阅读本文的读者来说,从 8.3.0: party 版本以来,重写现在是 npm 的一个支持特性: