默认 Nub 使用不需要垫片:nub installnub addnub run 已经提供并运行固定的包管理器。垫片用于你宁愿直接输入管理器的情况——裸 pnpm installnpm ciyarn add——并仍让它通过 Nub。一个命令开启它。

$ nub pm shim
nub pm shim: 6 entries in ~/.nub/shims (6 created)
PATH: added ~/.nub/shims to PATH (~/.zshrc) — restart your shell
$ which pnpm
~/.nub/shims/pnpm
$ pnpm --version
pnpm@9.5.0 (via nub shim)
Installing... (4 MB)
Installed in 0.8s
9.5.0

nub pm shim 之后,裸 pnpm 解析到 ~/.nub/shims 中的垫片——Nub 二进制的硬链接。在冷缓存上,pnpm --version(或任何固定 PM 命令)提供固定的 pnpm,然后在项目的 Node 下进程内分派。暗淡的 pnpm@9.5.0 (via nub shim) 行命名它运行的管理器和版本;它在每次分派时打印到 stderr,所以从不污染管道 stdout。要移除垫片,nub pm unshim 删除垫片目录并剥离 PATH 块,恢复之前的 pnpm

$ nub pm unshim
nub pm unshim: removed /Users/you/.nub/shims
  PATH: removed the shims block from /Users/you/.zshrc

垫片 vs 固定

两个独立步骤。固定位于 package.json 中:nub pm use pnpm 写入 packageManager 字段(和 devEngines.packageManager 范围)并对齐锁文件,设置项目使用哪个管理器。它不触碰你的 PATH 或安装任何垫片。

设置固定后,nub install 已经运行正确的 pnpm。垫片是单独的可选选择,使 pnpm 命令——在 shell 中输入的,或由你无法控制的工具调用的——也通过 Nub 路由。用 nub pm use 设置固定;如果你要拦截裸命令,用 nub pm shim 一次性安装垫片。

每调用开销

垫片位于每个命令前面,所以重要的是它增加的时间。Corepack 风格的垫片是 Node 脚本(#!/usr/bin/env node),所以调用它会引导 Node 解释器来读取你的固定并在任何安装工作开始前加载管理器。Nub 垫片是原生二进制的硬链接:解析固定并分派的进程是已在运行的——包管理器前面没有额外的解释器。

默认严格

在固定项目中,垫片拒绝运行不同的包管理器——竞争锁文件和 node_modules 正是你不想要的。在 pnpm 固定项目中裸 yarn add react 以非零退出并命名应该运行什么:

$ yarn add react   # ❌ 此项目的包管理器错误
nub: the nub package-manager shims on your PATH (installed via
     `nub pm shim`) intercepted this.
This project pins pnpm (via package.json#packageManager) — refusing to run yarn.
A different package manager here would write a competing lockfile
and node_modules.

  run instead:  pnpm add react
  to bypass:    invoke the system yarn by absolute path,
                or remove the shims: nub pm unshim

运行器命令保持透明。npxpnpx 工具以及 init / create / dlx / exec 动词无论固定如何都回退到系统工具,所以 npm create vite 在 pnpm 项目中工作。由运行安装生成的包管理器——生命周期脚本 shell 出到不同管理器——也回退,所以你从不到直接输入的安装不被破坏。