pnpm 支持带 Scheme 的 peerDependencies 说明符:named-registry、npm: 别名与 file:/git/URL 规范的匹配规则详解 包管理器开发工具CLI【免费下载链接】pnpmFast, disk space efficient package manager项目地址https://gitcode.com/gh_mirrors/pn/pnpm点击查看免费下载导读本文围绕 pnpm 对peerDependencies字段校验规则的变更对应.changeset/peer-scheme-specifiers.md系统讲解 pnpm 与 pacquetpnpm 的 Rust 实现本仓库 pnpm/crates 即其源码如何从一刀切拒绝演进为按 scheme 解析匹配peer 声明现在可以写成work:5.x.x、npm:bar^5、file:../pkg或 git/URL 等带 scheme 的说明符匹配时按说明符携带的 semver 范围校验安装时仍由原始说明符选择包。读完你将掌握哪些 peer 声明格式合法、每种格式如何提取匹配范围、裸nameversion为何仍被拒绝以及这条规则在源码中的完整实现链路。一、变更背景peerDependencies 曾经拒绝一切非常规说明符在peerDependencies中声明格式长期被严格限制为合法的 semver 范围如^5.0.0、1.0.0 2.0.0workspace:/catalog:引用。一旦出现其他写法pnpm 会以错误码ERR_PNPM_INVALID_PEER_DEPENDENCY_SPECIFICATION中止安装报错信息形如The peerDependencies field named {dep_name} of package {project_id} has an invalid value: {specifier}该错误在 Rust 实现中的定义位于 resolve_dependency_tree.rs其 help 文本明确给出了合法值范围The values in peerDependencies should be a valid semver range, aworkspace:/catalog:spec, or a dependency specifier such as a named-registry (registry:version),npm:,file:, or git/URL spec也就是说pnpm 此前虽然已经认识到这些带 scheme 的说明符应该合法但校验逻辑并不接受它们导致work:5.x.x、npm:bar^5这类写法直接报错对应 issue #13095。本次变更minor 级正是补齐了这一缺口允许 scheme-carrying 说明符进入peerDependencies。二、变更内容现在接受哪些 peer 说明符依据 changesetpeerDependencies现在接受携带 scheme 的依赖说明符包括以下四类类别写法示例说明named-registry 说明符work:5.x.x、gh:scope/pkg^1.0.0registry:version形式指向配置的命名 registry 别名npm:别名npm:bar^5通过 npm registry 安装别名为其他名字的包file:说明符file:../vendor/real-peer指向本地目录或文件git / URL 说明符github:user/repo、https://...指向 git 仓库或 tarball URL其中named-registry别名机制在本仓库有完整支撑用户可通过pnpm-workspace.yaml声明 registry 别名见 settings.rs内置别名在 defaults.rs 定义alias:scope/pkg这类带 scope 的说明符由 named-registry resolver 专门拆分处理见 resolver_setup.rs。三、匹配规则从说明符中提取 semver 范围允许写法只是第一步关键是如何匹配——peer 依赖最终要与实际安装的版本做兼容性校验。核心规则对应 TypeScript 包pnpm/deps.peer-rangeRust 镜像实现于 peer_range.rs声明写法提取出的匹配范围说明work:5.x.x5.x.xnamed-registry 说明符取其版本体npm:bar^5^5取之后的版本部分带 scheme 但无版本*如file:、git/URL 说明符没有版本信息workspace:1.2.31.2.3剥掉前缀后剩余部分是范围则直接用workspace:^/workspace:~/workspace:*无版本可提取视为任意版本纯 semver 范围原样返回^5.0.0仍是^5.0.0catalog:引用原样返回由 catalog 解析处理work:^1 \|\| work:^2^1 \|\| ^2多个消费者范围合并后的\|\|联合逐一提取版本体该规则由 get_peer_version_range 实现分三步若含||先按联合拆分、对每个子项递归处理再重新 join若是合法 peer 范围semver /workspace:/catalog:交给desugar_workspace_range处理workspace:前缀否则寻找:要求位置不在首位取其后的版本体若版本体本身是合法范围直接使用若形如bar^5则取最后一个之后的部分仍解析不出则返回*。设计意图很清晰匹配范围只决定这个版本是否满足 peer 要求而安装时选哪个包由原始说明符决定。例如file:../vendor/real-peer匹配范围是*任何版本都满足但实际安装的永远是../vendor/real-peer这个本地目录。四、仍被拒绝裸nameversion规则收紧的另一面是裸的nameversion值如foo1.0.0几乎总是笔误仍然被拒绝。这类写法没有 scheme 前缀又不是合法 semver 范围校验时会被判为非法。拒绝逻辑见 is_acceptable_peer_spec一个 peer 值只有在是合法范围semver/workspace:/catalog:或包含:时才被接受。foo1.0.0两者都不满足于是报ERR_PNPM_INVALID_PEER_DEPENDENCY_SPECIFICATION。校验的入口在 importer.rs 的validate_peer_dependencies它遍历 manifest 中所有DependencyGroup::Peer条目对每个(dep_name, specifier)调用is_acceptable_peer_spec一旦发现非法值立即返回InvalidPeerDependencySpecification错误其中project_id取 manifest 的name字段、缺失时回退到目录路径。注释点明了这样做的原因拒绝裸nameversion是为了避免这类笔误被当作项目相对路径依赖name/version会被解析成目录而悄悄解析成功。五、peer 自动安装scheme 如何参与选择与去重peer 说明符的 scheme 不仅在校验时起作用还贯穿缺失 peer 自动安装流程在 missing_peers.rs当多个消费者对同一 peer 声明了不同范围时classify_missing_peer合并这些范围注释明确说明hoisting 一个缺失的必需 peer 时需要保留原始说明符的 scheme如work:5.x.x因为要按该说明符去拉取包而范围合并只负责产生一个可比较的版本区间。在 hoist_peers.rspreferred_version_specifier选择去重目标版本时调用get_peer_version_range把 scheme 说明符还原成可比范围如果某 importer 已解析出一个满足该范围的版本就直接复用dedupe onto a preferred version若存在候选版本但都不满足范围则回退为用范围本身从 registry 解析而不是硬装一个 peer 明确拒绝的版本。对于没有版本体的说明符如catalog:、dist-tag提取结果不是 semver则保持去重到最高版本的旧行为。六、测试与验证本仓库围绕该特性提供了三层测试可作为行为规范Rust 单元测试peer_range/tests.rs 中is_acceptable_peer_spec_accepts_scheme_carrying_specifiers验证 scheme 说明符被接受、get_peer_version_range_reduces_a_union_of_scheme_specifiers验证||联合提取importer_wanted_specs.rs 的accepts_scheme_carrying_peer_specifiers验证整条 importer 解析链路放行这些说明符。CLI 集成测试cli/tests/suite/peers.rs 覆盖ERR_PNPM_INVALID_PEER_DEPENDENCY_SPECIFICATION错误码的端到端表现。TypeScript 侧镜像实现pnpm/deps.peer-range对应的校验逻辑在 validatePeerDependencies.ts配套测试见 validatePeerDependencies.ts。Rust 侧注释明确要求与 TS 侧保持同步keep the two in sync。七、实战配置示例在package.json中声明带 scheme 的 peer 依赖{ name: my-plugin, peerDependencies: { workbox: work:5.x.x, bar: npm:bar^5, real-peer: file:../vendor/real-peer } }解析行为对应如下安装时validate_peer_dependencies先放行全部三项都含:解析/校验时分别按5.x.x、^5、*匹配消费者实际安装的版本若某 peer 缺失需要自动安装则用work:5.x.x、npm:bar^5、file:../vendor/real-peer原样作为拉取说明符若有人误写成workbox: workbox5.0.0安装立即以ERR_PNPM_INVALID_PEER_DEPENDENCY_SPECIFICATION失败并提示正确写法。八、影响范围与注意事项本次变更在 changeset 中以 minor 级发布同时作用于pnpmTypeScript 实现与pacquetRust 实现并同步 bump 了pnpm/deps.peer-rangeminor、pnpm/installing.deps-resolver与pnpm/deps.inspection.peers-checkerpatch。兼容性原合法的 semver、workspace:、catalog:行为完全不变npm:别名、named-registry、file:/git/URL 由报错变为可解析属向后兼容的放宽裸nameversion的拒绝行为保持不变不会静默放行。使用前提named-registry 说明符依赖项目已配置对应的 registry 别名内置别名见 defaults.rs用户别名经pnpm-workspace.yaml声明参见 settings.rsfile:/git 说明符需要对应目录或仓库可达。匹配语义提醒file:/git/URL 说明符的匹配范围是*意味着 peer 兼容性检查不会因版本号产生警告但这不代表任意版本都合理——peer 的实际内容兼容性仍由声明方自行保证pnpm 只负责安装时按原始说明符取包。总结peer-scheme-specifiers这项变更让 pnpm 的peerDependencies从严格 semver 白名单演进为scheme 感知的说明符解析named-registry、npm:别名、file:/git/URL 说明符各按其携带的版本体参与匹配无版本则匹配*原始说明符始终负责选择安装目标裸nameversion笔误则继续被ERR_PNPM_INVALID_PEER_DEPENDENCY_SPECIFICATION拦截。核心判定与范围提取集中在 peer_range.rs校验入口在 importer.rs自动安装的 scheme 保留与去重逻辑分别在 missing_peers.rs 与 hoist_peers.rs三层测试用例可作为行为规范的最终依据。赞分享包管理器开发工具CLI【免费下载链接】pnpmFast, disk space efficient package manager项目地址https://gitcode.com/gh_mirrors/pn/pnpm点击查看免费下载相关推荐Nativefier URL重写规则文档规则说明与示例Nativefier URL重写规则文档规则说明与示例 一、URL重写功能概述 URL重写URL Rewrite是Nativefier中用于修改网页请求U桌面应用CLI从WaveNet到DiffSingerawesome-speech-recognition-speech-synthesis-papers语音合成技术深度解析从WaveNet到DiffSingerawesome speech recognition speech synthesis papers语音合成技术深度解析KubeEdge 依赖解析containerd/platforms 平台说明符语法、规范化与匹配机制全解KubeEdge 依赖解析containerd/platforms 平台说明符语法、规范化与匹配机制全解 导读 容器平台Container Platform云原生边缘计算物联网容器编排边缘网关创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考