npm
Nub 使用 npm 的磁盘格式——版本 2 和版本 3 锁文件逐字节往返,npm 工作区和覆盖被遵守,npm 配置在内置、全局、用户和项目范围中读取。CLI 是 pnpm 形态的;文件是 npm 的。
你输入的 CLI 是 pnpm 形态的;Nub 读取和写入的文件是 npm 的。当 npm 是现任者——packageManager: "npm@…" 字段或现有的 package-lock.json——Nub 以其原生格式读取和写入 npm 自身的 package-lock.json,遵守 npm 的配置级联,且不引入 pnpm-lock.yaml。以下所有内容以此为前提。
配置
| 功能 | npm | nub | 备注 |
|---|---|---|---|
dependencies / devDependencies | 支持 | 支持 | |
optionalDependencies | 支持 | 支持 | |
peerDependencies / peerDependenciesMeta | 支持 | 支持 | |
overrides | 支持 | 支持 | |
engines / os / cpu / libc | 支持 | 支持 | |
packageManager | 支持 | 支持 | |
bundleDependencies | 支持 | 支持 | |
workspaces | 支持 | 支持 | |
| 工作区范围 | 支持 | 支持 | |
| 工作区选择器 | 支持 | 部分支持. 无 git-since ([ref]) 选择器。无 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。 | v1(npm 5/6)读取;首次变更安装时重写为 v3。 |
npm-shrinkwrap.json | 支持 | 支持. 包括 2017 年前(嵌套,无 lockfileVersion)。包括 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 add、nub remove)将其重写为 v3(npm 9 起的默认值),所以版本字段是预期的差异。npm-shrinkwrap.json 被读取并原样保留。
旧格式也被读取。lockfileVersion: 1 锁文件(npm 5/6)和 2017 年前的 npm-shrinkwrap.json——没有 lockfileVersion 字段的嵌套 dependencies 树——两者都解析和安装:Nub 将旧版嵌套树提升到它用于 v2/v3 的相同安装路径方案。注册表依赖完全安装。首次变更操作(nub add、nub 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-strict 和 save-exact。npm_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——无操作安装保持传入版本。
- 无直接替代的
npmCLI 语法。 npm 特定的子命令拼写和标志不被模拟;CLI 是 pnpm 形态的。