你输入的 CLI 是 pnpm 形态的;Nub 读取和写入的文件是 npm 的。当 npm 是现任者——packageManager: "npm@…" 字段或现有的 package-lock.json——Nub 以其原生格式读取和写入 npm 自身的 package-lock.json,遵守 npm 的配置级联,且不引入 pnpm-lock.yaml。以下所有内容以此为前提。

配置

功能npmnub备注
dependencies / devDependencies支持支持
optionalDependencies支持支持
peerDependencies / peerDependenciesMeta支持支持
overrides支持支持
engines / os / cpu / libc支持支持
packageManager支持支持
bundleDependencies支持支持
workspaces支持支持
工作区范围支持支持
工作区选择器支持部分支持. 无 git-since ([ref]) 选择器。无 git-since ([ref]) 选择器。
项目 + 用户 .npmrc支持支持
全局 + 内置 .npmrc支持支持
npm_config_*支持支持
NPM_CONFIG_* / NPM_TOKEN支持支持
package-lock.json v1 / v2 / v3支持支持. v1(npm 5/6)读取;首次变更安装时重写为 v3。v1(npm 5/6)读取;首次变更安装时重写为 v3。
npm-shrinkwrap.json支持支持. 包括 2017 年前(嵌套,无 lockfileVersion)。包括 2017 年前(嵌套,无 lockfileVersion)。

package-lock.json

Nub 读取 lockfileVersion 2 和 3,针对它解析,并以 npm 的精确格式写回。在无操作安装时,写入器逐字节重现 npm 的输出——键排序、devOptional 折叠、peerDependenciesMeta.optional 和平台字段都保留——所以文件不抖动且 npm ci 不变地接受它。

// 来自 `nub install` 的 package-lock.json — `npm ci` 逐字节接受
{
  "name": "app",
  "version": "1.0.0",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "": {
      "name": "app",
      "version": "1.0.0",
      "dependencies": { "is-odd": "3.0.1" }
    },
    "node_modules/is-odd": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-3.0.1.tgz",
      "integrity": "sha512-CQpnWPrD…CBaXgWMA==",
      "license": "MIT",
      "dependencies": { "is-number": "^6.0.0" },
      "engines": { "node": ">=4" }
    }
  }
}

无操作重写保持传入的 lockfileVersion——v2 锁文件保持 v2。首次变更操作(nub addnub remove)将其重写为 v3(npm 9 起的默认值),所以版本字段是预期的差异。npm-shrinkwrap.json 被读取并原样保留。

旧格式也被读取。lockfileVersion: 1 锁文件(npm 5/6)和 2017 年前的 npm-shrinkwrap.json——没有 lockfileVersion 字段的嵌套 dependencies 树——两者都解析和安装:Nub 将旧版嵌套树提升到它用于 v2/v3 的相同安装路径方案。注册表依赖完全安装。首次变更操作(nub addnub remove)将锁文件重写为 v3,与 npm 7+ 执行的就地升级相同。

两个旧版边界仍不在范围内。v1 锁文件中编码在 version 字段而非 resolved 中的 Git 和 file: 依赖尚未被读取。以及一个完全不记录 requires 边的、完全提升的 npm 5 前 shrinkwrap 无法放置每个传递依赖——Nub 安装它能安装的并警告其余的(WARN_NUB_LOCKFILE_LEGACY_INCOMPLETE_GRAPH)。对于任一情况,先在 npm 7+ 下重新锁定,然后 nub install

.npmrc

当 npm 是现任者时,Nub 读取 npm 的 .npmrc 级联:

builtin   npm 的内置 npmrc
global    $PREFIX/etc/npmrc,或 NPM_CONFIG_GLOBALCONFIG
user      ~/.npmrc,或 NPM_CONFIG_USERCONFIG
project   ./.npmrc

这些范围内的所有内容都有效——默认和 scope 注册表、认证令牌、TLS、代理,以及安装塑形键如 engine-strictsave-exactnpm_config_* 环境变量也驱动安装行为。优先级与 npm 一致,最高在前:CLI 标志,然后 npm_config_*,然后项目、用户、全局和内置 .npmrc

自定义 CA

企业或自签名证书颁发机构通过标准 npm TLS 键配置,顶层或限定到一个注册表:

# .npmrc
cafile=./corp-ca.pem                          # PEM 包,所有注册表
//registry.example.com/:cafile=./corp-ca.pem  # 每注册表覆盖
# 内联 PEM(重复 ca[]= 来堆叠)
ca="-----BEGIN CERTIFICATE-----..."
# 禁用验证(仅用户/全局范围)
strict-ssl=false

证书被添加到安装客户端的信任存储中。提交的项目 .npmrc 不能关闭 strict-ssl——只有用户或全局范围可以。

配置

当 npm 是现任者时,Nub 遵守 npm 的图塑形字段:

  • overrides — npm 自身的版本固定字段(npm 8.3+),在解析期间应用并写入锁文件。
  • workspaces — 中性成员数组,加上 npm 的 --workspace / --workspaces 标志。
  • engines / os / cpu / libc — 解析期间执行的平台字段。
// package.json
{
  "overrides": { "is-number": "7.0.0" },
  "workspaces": ["packages/*"]
}

npm 忽略 Yarn 风格的顶层 resolutions,所以 Nub 在 npm 现任者下丢弃它并警告。使用 overrides

安装行为

默认 node_modules 布局是隔离的——直接依赖在顶层,传递依赖在每项目虚拟存储中,幻影(未声明的)依赖失败而非意外解析。这比 npm 的扁平树更严格,所以依赖未声明传递依赖的项目通过 .npmrc 中一行选择回退:

node-linker=hoisted

当未声明的包在运行时解析失败时,Nub 的错误命名它并指向此退出选项。

生命周期脚本在 Nub 的拒绝默认信任策略加上门控的默认信任下限下运行(参见默认信任下限),而非 npm 的运行一切默认值。精选的、经年龄审查的包自动构建;其他一切跳过并带 WARN_NUB_IGNORED_BUILD_SCRIPTS 直到 nub approve-builds。平台门控的可选依赖(例如 fsevents)解析并往返到锁文件中。

差距

  • 旧版 git / file: 依赖在 v1 锁文件中(源码编码在 version 中,不是 resolved)尚未被读取——先在 npm 7+ 下重新锁定。
  • v1 或 v2 锁文件在首次变更安装时变为 v3——无操作安装保持传入版本。
  • 无直接替代的 npm CLI 语法。 npm 特定的子命令拼写和标志不被模拟;CLI 是 pnpm 形态的。