Nub 读取你项目的包管理器固定,从 npm 注册表获取该确切版本——完整性验证、缓存在 ~/.cache/nub/pm 下——并在项目的 Node 上运行它。无 corepack、无 enable 步骤、无内置版本表:六个月前的 Nub 二进制提供今天的 pnpm。

$ nub pm which
/Users/you/.cache/nub/pm/pnpm/9.15.4/package/bin/pnpm.cjs
» resolved from packageManager (pnpm@9.15.4)

固定解析

固定从工作区根目录的两个 package.json 字段按顺序读取:

  1. packageManager — corepack 字段。仅精确(pnpm@9.15.4,可选 +sha512.<hash>)。
  2. devEngines.packageManager{ name, version };版本可以是范围。

范围属于 devEngines;corepack、pnpm 和 Yarn 都在 packageManager 中拒绝它们。两个字段都无固定时,nub pm which 报错并指向 nub pm use。锁文件从不隐含固定。

多个锁文件

两个 PM 的锁文件并排(pnpm-lock.yamlpackage-lock.json)是歧义的——Nub 报错(ERR_NUB_LOCKFILE_AMBIGUOUS)。删除过时的,或用 nub pm use 声明固定。

Yarn Berry

提交的 Berry 发布(.yarnrc.yml yarnPath)优先于上方的固定字段。Nub 直接运行提交的文件且从不提供 Berry,所以无提交发布的 yarn@2+ 固定报错。Yarn classic(1.x)像任何其他管理器一样提供。

CLI

nub pm which

打印解析的包管理器——路径在 stdout,来源在 stderr,所以 PM=$(nub pm which) 只捕获路径。如果尚未缓存则提供固定版本。

$ nub pm which
/Users/you/.cache/nub/pm/pnpm/9.15.4/package/bin/pnpm.cjs
» resolved from packageManager (pnpm@9.15.4)

nub pm use

声明项目的包管理器——npm、pnpm、Yarn 或 Bun。一个命令解析版本(精确、范围或 dist-tag;裸表示 latest),获取并验证它,写入 packageManager,并对齐锁文件。

nub pm use pnpm           # 最新 pnpm
nub pm use npm@10         # 最新 10.x
nub pm use pnpm@9.15.4    # 精确

将 npm 项目移到 pnpm:

$ nub pm use pnpm
Fetching pnpm 11.5.3 (4 MB)...
using pnpm@11.5.3
  package.json: packageManager = pnpm@11.5.3 (+sha512)
  package.json: devEngines.packageManager =
    { name: "pnpm", version: "^11.5.3", onFail: "warn" }
  pnpm-lock.yaml: written (converted from package-lock.json)
  package-lock.json: removed (migrated)

它写入什么:

  • package.json#/packageManager — 精确版本加来自已验证 tarball 的 +sha512 哈希。corepack、pnpm 和 turbo 执行的;use 是唯一写入它的 Nub 命令。
  • package.json#/devEngines/packageManager{ name, version: "^<exact>", onFail: "warn" },npm 和 pnpm 原生执行的范围加策略形式,写在精确固定旁边以使两者不能漂移。
  • 锁文件,以新管理器的格式。 另一格式的锁文件被转换——解析状态保留——旧文件被删除。已为目标格式的保持不变;无锁文件时,下次安装创建它。转换的锁文件通过活跃管理器的冻结安装(pnpm install --frozen-lockfile 等)逐字节。

配置不迁移

切换管理器转换锁文件,不转换你的配置。.npmrc、任何 pnpm.* 字段、pnpm-workspace.yaml 设置和其他管理器特定配置保持原样——Nub 不翻译它们。自行携带新管理器需要的任何内容。

写入或删除的每个文件都在输出中命名;重新运行是无操作。拒绝,全在写入任何东西之前:

  • 多个外来格式锁文件 — 先删除过时的。
  • 二进制 bun.lockb — 先用 bun install --save-text-lockfile 重新生成为文本。
  • use yarn 到 Berry(2+)yarn.lock — classic 会降级格式;使用 yarn set version
  • use yarn 在使用 workspace: 协议的图上 — classic yarn 无法表达它。

否则转换的 use yarn 没问题——Nub 直接写入 classic yarn.lock。运行 use bun 写入固定和锁文件但不提供 bun。

nub pm pin

将项目锁定到精确 Nub 版本。裸运行固定你正在运行的 Nub;传递版本固定特定版本。

nub pm pin           # 固定正在运行的 Nub
nub pm pin 0.2.10    # 固定精确版本
$ nub pm pin
pinned nub@0.2.10
  package.json: packageManager = nub@0.2.10
  package.json: devEngines.packageManager = { name: "nub", version: "^0.2.10", onFail: "warn" }

它只写入身份字段——精确 packageManager 固定和旁边的 devEngines.packageManager 插入符号——不写入其他任何东西:无锁文件转换、无配置迁移。更完整的切换到 Nub 是 nub pm use nub 的工作;pin 是轻量级锁,Nub 的 Node 固定的包管理器类比。

版本必须精确——Nub 是你正在运行的二进制文件,不是注册表包,所以范围或 dist-tag 无可解析。

nub pm update

提升固定:解析满足 devEngines 范围的最新版本(或无范围时注册表 latest),提供它,并用新哈希重写 packageManager。别名:nub pm up

$ nub pm update
Fetching pnpm 9.15.9 (4 MB)...
updated pnpm 9.15.4 → 9.15.9

nub pm cache

检查或清除包管理器缓存。

$ nub pm cache
pnpm@9.15.4
yarn@1.22.22
$ nub pm cache clear

版本位于 ~/.cache/nub/pm/<pm>/<version>。缓存的精确固定完全离线运行——注册表仅在解析范围和获取缺失版本时联系。提供的管理器以热的 V8 编译缓存(NODE_COMPILE_CACHE)运行,所以 PM 的数兆字节包以缓存字节码加载而非每次调用重新解析。

nub pm shim

垫片是可选的:运行 nub pm shim,裸 pnpmnpmyarn 命令通过 Nub 路由到固定管理器,nub pm unshim 移除它们。默认使用不需要这些——nub installnub run 已经运行固定。参见包管理器垫片了解安装、默认严格拒绝和每调用开销。

固定 Nub 自身

packageManager 字段也可以固定 Nub——nub@X.Y.Z。当正在运行的 Nub 是不同版本时,它获取该确切发布、验证并移交,所以项目的安装不依赖于每个贡献者碰巧有的 Nub。

{
  "packageManager": "nub@0.2.9"
}

移交在安装动词上运行——结果是提交的锁文件和 node_modules

$ nub install
nub: provisioning pinned nub@0.2.9 (darwin-arm64)...
nub: provisioned nub@0.2.9

发布来自 Nub 自身的渠道并在运行前校验和验证;损坏、缺失或错误版本的构建是硬错误,从不是静默回退。存储位于 ~/.cache/nub/self/<version>,所以固定版本提供后离线运行。

只有安装动词移交。其他一切——文件运行器、脚本运行、nubx、版本管理、自更新——从不读取固定,所以 nub script.ts 保持快速。匹配的固定就地运行。非精确固定也如此,带通知:与 corepack 一样,packageManager 字段仅精确。

要无论固定如何都用你安装的 Nub 运行,设置 NUB_SELF_SHIM=0。它为整个树禁用移交:

NUB_SELF_SHIM=0 nub install

.npmrc

PM 下载——packument 和 tarball——通过你的 .npmrcregistry= 选择镜像,//host/:_authToken= 认证。需要认证的 Artifactory/Nexus 镜像以你已有的配置工作:

registry=https://npm.corp.example
//npm.corp.example/:_authToken=${CORP_NPM_TOKEN}

要从与依赖不同的注册表获取包管理器,COREPACK_NPM_REGISTRY(+ COREPACK_NPM_TOKEN)覆盖 PM 下载注册表——从 corepack 迁移的团队保留其现有 CI 变量。