Rush Stack商店博客活动
跳至主要内容

首选版本

背景

Rush 通过在您的公共文件夹中创建一个引用包含每个项目依赖项的 tarball 的假 **rush-common** 项目,为所有项目执行一次安装。例如,假设您的 **rush.json** 有两个项目“**project1**”和“**project2**”。生成的 文件可能如下所示

common/temp/package.json

{
"name": "rush-common",
"description": "Temporary file generated by the Rush tool",
"private": true,
"version": "0.0.0",
"dependencies": {
"@rush-temp/project1": "file:./projects/project-1.tgz",
"@rush-temp/project2": "file:./projects/project-2.tgz"
}
}

包管理器将这些“**@rush-temp**”作用域项目中的每一个都视为 **rush-common** 项目的直接依赖项。通常,NPM 首先安装项目的直接依赖项(在 **node_modules** 树的根目录中),然后才下载间接依赖项。但是,由于您实际项目的直接依赖项现在是 **rush-common** 项目的间接依赖项,因此 npm install 行为可能会有所不同。

假设 **project-1/package.json** 如下所示

{
"name": "project-1",
"version": "1.0.0",
"dependencies": {
"library-a": "1.0.1",
"library-b": "1.1.3"
}
}

假设 **library-a**(来自互联网)如下所示

{
"name": "library-a",
"version": "1.0.1",
"dependencies": {
"library-b": "^1.0.0"
}
}

如果您在 **project-1** 中运行正常的 npm install,您将期望有一个 **node_modules** 文件夹,即使 **library-b@1.4.4** 存在于 NPM 仓库中,也应该如下所示

node_modules/
library-a/ (1.0.1)
library-b/ (1.1.3)

即使 **library-b@1.4.4** 与 "^1.0.0" SemVer 模式匹配,NPM 也不会安装它,因为 1.1.3(由 project-1 安装)已经满足了它。

但是上面描述的 **common/temp/package.json** 无法保证这一点。相反,根据 **project-2** 的依赖关系,您最终可能会得到以下结果

node_modules/
project-1/
library-b/ (1.1.3)
library-a/ (1.0.1)
library-b/ (1.4.4)

...这也是 SemVer 等式的有效解决方案。在将 Rush 与 NPM 的 同级依赖项 一起使用时,可能会出现类似的问题。

首选版本

为了控制这些影响,Rush 引入了“首选版本”的概念,这些版本是明确添加到顶层 **common/temp/package.json** 中的依赖项。

您可以通过将版本添加到配置文件 **common-versions.json** 中来“锁定”它。例如

common/config/rush/common-versions.json

{
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/common-versions.schema.json",
"preferredVersions": {
"css-loader": "1.2.3"
}
}

这将导致 **css-loader** 被添加到我们上面示例中的 **common/temp/package.json** 中,如下所示

{
"name": "rush-common",
"description": "Temporary file generated by the Rush tool",
"private": true,
"version": "0.0.0",
"dependencies": {
"css-loader": "1.2.3",
"@rush-temp/project1": "file:./projects/project-1.tgz",
"@rush-temp/project2": "file:./projects/project-2.tgz"
}
}

注意:如果您发布包,则在添加首选版本时应谨慎,这样不会产生与使用 NPM 正常安装库的人员不同的结果。

隐式首选版本

默认情况下,Rush 会自动将所有项目的直接依赖项添加到 **common/temp/package.json** 中。在我们最初的示例中,这些“隐式首选版本”可能如下所示

common/temp/package.json

{
"name": "rush-common",
"description": "Temporary file generated by the Rush tool",
"private": true,
"version": "0.0.0",
"dependencies": {
"css-loader": "1.2.3", // <---- preferred version that was specified above
"library-a": "~1.0.0", // <---- implicitly preferred version
"library-b": "1.1.3", // <---- implicitly preferred version
"@rush-temp/project1": "file:./projects/project-1.tgz",
"@rush-temp/project2": "file:./projects/project-2.tgz",
}
}

Rush 会为您执行此操作,除非在不同的项目为给定依赖项指定了不同的版本范围。在这种情况下,Rush 将无法确定应隐式首选哪个版本。例如,如果 **project1** 和 **project2** 请求不同版本的 **library-b**,那么您可能需要介入,并可能使用 **common-versions.json** 来解决您的问题。

对于较旧的包管理器,自动添加这些条目往往会减少间接依赖项的重复。但是,隐式首选版本可能会对具有不兼容的 peerDependencies 范围的某些依赖项造成问题。如果您遇到与同级依赖项相关的安装错误,我们建议您通过在 common/config/rush/common-versions.json 配置文件中将 implicitlyPreferredVersions 设置为 false 来禁用此行为。