pnpm
Nub 最紧密地镜像 pnpm——原生版本 9 锁文件读写、完整的依赖动词接口、工作区选择器、隔离依赖树和 pnpm 拥有的配置,都以 pnpm 是现任者为前提。
Nub 最紧密地镜像 pnpm:CLI 接口、隔离的 node_modules 布局和锁文件。当 pnpm 是现任者——packageManager: "pnpm@…" 字段或现有的 pnpm-lock.yaml——Nub 以其原生格式读取和写入 pnpm 自身的 pnpm-lock.yaml,并遵守 pnpm 的配置。以下所有内容以此为前提。
命令
| 功能 | pnpm | nub | 备注 |
|---|---|---|---|
install / i / ci | 支持 | 支持 | |
add / remove / update | 支持 | 支持 | |
import | 支持 | 支持 | |
dedupe / prune | 支持 | 支持 | |
rebuild / fetch | 支持 | 支持 | |
link / unlink | 支持 | 支持 | |
patch / patch-commit / patch-remove | 支持 | 支持 | |
approve-builds / ignored-builds | 支持 | 支持 | |
dlx / create | 支持 | 支持 | |
list / why / outdated | 支持 | 支持 | |
audit / licenses / peers | 支持 | 支持 | |
publish / pack / version | 支持 | 支持 | |
store / config | 支持 | 支持 | |
recursive 元动词 | 支持 | 支持 | |
deploy | 支持 | 不支持. 未接入;pnpm deploy 暂时仍是路径。未接入;pnpm deploy 暂时仍是路径。 | 未接入;pnpm deploy 暂时仍是路径。 |
配置
| 功能 | pnpm | nub | 备注 |
|---|---|---|---|
dependencies / devDependencies | 支持 | 支持 | |
optionalDependencies | 支持 | 支持 | |
peerDependencies / peerDependenciesMeta | 支持 | 支持 | |
dependenciesMeta.injected | 支持 | 支持 | |
pnpm.overrides | 支持 | 支持 | |
pnpm.packageExtensions | 支持 | 支持 | |
pnpm.patchedDependencies | 支持 | 支持 | |
resolutions | 支持 | 支持 | |
onlyBuiltDependencies / neverBuiltDependencies | 支持 | 支持 | |
packageManager / engines | 支持 | 支持 | |
workspaces / pnpm-workspace.yaml | 支持 | 支持 | |
catalog: / catalogs: | 支持 | 支持 | |
workspace: 协议 | 支持 | 支持 | |
| 工作区选择器 | 支持 | 部分支持. 无 git-since ([ref]) 选择器。无 git-since ([ref]) 选择器。 | 无 git-since ([ref]) 选择器。 |
.npmrc | 支持 | 支持 | |
.pnpmfile.cjs / .pnpmfile.mjs | 支持 | 支持 | |
npm_config_* | 支持 | 支持 | |
pnpm_config_* | 支持 | 支持 | |
pnpm-lock.yaml v9 | 支持 | 支持. v6/v5.4 被拒绝——在 pnpm 9+ 下重新锁定。v6/v5.4 被拒绝——在 pnpm 9+ 下重新锁定。 | v6/v5.4 被拒绝——在 pnpm 9+ 下重新锁定。 |
nodeLinker | 支持 | 部分支持. 无 PnP。无 PnP。 | 无 PnP。 |
锁文件
Nub 读取和写入 pnpm 锁文件 v9(lockfileVersion: '9.0')——pnpm 9+ 发出的版本。Nub 写入的锁文件在 pnpm 下干净安装:
$ nub install
dependencies:
+ is-odd@3.0.1
$ grep lockfileVersion pnpm-lock.yaml
lockfileVersion: '9.0'
$ pnpm install --frozen-lockfile
Lockfile is up to date, resolution step is skipped双向往返都成立,对单个包和带 catalog: 和 workspace: 条目的工作区(针对 pnpm 10.15.1 验证)。
旧格式——v6(pnpm 8)和 v5.4(pnpm 7)——将根依赖放在顶层 dependencies: 映射下,而非 v9 的 importers:。Nub 预先拒绝它们,保持你的 node_modules 和锁文件不变:
# 捕获:nub 0.0.44 在 lockfileVersion: '6.0' 锁文件上
$ nub install
Error: ERR_NUB_LOCKFILE_UNSUPPORTED_FORMAT
× pnpm-lock.yaml is lockfileVersion 6.0 (pnpm 8); nub reads v9 (pnpm 9+).
help: Re-lock under pnpm 9+ (`pnpm install`), then `nub install`.拒绝命名检测到的版本(v5.4 读取 (pnpm 7))。通过在 pnpm 9+ 下运行一次 pnpm install 来升级锁文件到 v9,然后 nub install 迁移。
配置
当 pnpm 是现任者时,Nub 遵守 pnpm 的配置接口:
pnpm-workspace.yaml—packages:glob 和catalog:/catalogs:映射。pnpm.overrides— 解析期间应用的版本固定,写入锁文件的overrides:块。pnpm.packageExtensions— 合并到解析包上的额外依赖/peer 元数据,哈希到锁文件的packageExtensionsChecksum。pnpm.patchedDependencies— 链接期间应用到依赖内容的补丁文件,接入nub patch/patch-commit/patch-remove。pnpm.onlyBuiltDependencies/pnpm.neverBuiltDependencies/pnpm.allowBuilds— 供给 Nub 的生命周期脚本策略。.pnpmfile.cjs/.pnpmfile.mjs—readPackage、preResolution和afterAllResolved钩子运行。readPackage的依赖图编辑应用;afterAllResolved的包图编辑应用。不支持新的导入器/包、身份重写、updateConfig钩子和配置依赖 pnpmfile。
# pnpm-workspace.yaml
packages:
- 'packages/*'
catalog:
lodash.merge: 4.6.2// package.json
{
"pnpm": { "overrides": { "is-number": "7.0.0" } }
}overrides、packageExtensions 和 patchedDependencies 从 pnpm 接受的任一处读取——package.json 中的 pnpm.* 命名空间或 pnpm-workspace.yaml 中的匹配键。pnpm 解析器优先 pnpm.overrides;顶层 resolutions 仍被遵守(pnpm 为 Yarn 兼容性支持它),但顶层 overrides 是 npm/Bun 的字段,在 pnpm 下被忽略。
这些字段被遵守是因为项目是 pnpm 拥有的——packageManager: "pnpm@…" 声明或现有的 pnpm-lock.yaml。将 Nub 采用到现有 pnpm 仓库保持它 pnpm 拥有,所以三者不变地应用。只有将项目切换到 Nub 自身身份(nub pm use nub)才将它们迁移到中性 overrides / patchedDependencies package.json 字段。
在非 pnpm 现任者——npm、Yarn、Bun 或 Nub 身份项目——下,这些都不被读取。对于 npm、Yarn 和 Bun 现任者,游离的 .pnpmfile.cjs 被忽略并警告而非静默应用:
$ nub install
nub: `.pnpmfile.cjs` ignored — this project uses npm, which doesn't
apply pnpmfile hooks. Remove it, name it explicitly with
`--pnpmfile`, or switch to pnpm (`nub pm use pnpm`).在 Nub 身份下,pnpm 命名的文件不在支持的配置接口内,默认 .pnpmfile.cjs / .pnpmfile.mjs 文件被静默忽略。显式 --pnpmfile <path> 始终加载。
安装行为
默认 node_modules 布局是隔离的——pnpm 的符号链接到虚拟存储方案。--node-linker hoisted 标志给出扁平的 npm 风格布局。
没有 pnp linker。来自 .npmrc 或 --node-linker pnp 标志的 node-linker=pnp 请求被拒绝而非静默降级:
$ nub install
× node-linker=pnp is not supported by nub; use `isolated` (default) or # ❌
│ `hoisted`依赖的生命周期脚本默认跳过,与 pnpm 10 完全一致。包仅在通过 pnpm.onlyBuiltDependencies(或 pnpm.allowBuilds)白名单或 Nub 的门控默认信任下限为其担保时(参见默认信任下限)运行安装脚本;nub approve-builds 交互式添加条目。pnpm.neverBuiltDependencies 是优先于任何允许和下限的黑名单。
不支持
少数 pnpm 接口产生诚实的 unsupported-command 错误而非静默回退:
sbom # CycloneDX/SPDX 物料清单 — 未接入
deploy # 未接入;操作保持手动node-linker=pnp 安装模式也被拒绝;参见上方表格。