支持的软件包来源
pnpm 支持从各种来源安装软件包。这些来源分为两类:可信来源 和 外来来源 。
使用外来来源(例如 Git 仓库或直接 tarball URL)时,传递依赖项可能会引入依赖链风险。你可以通过将 blockExoticSubdeps 设置为 true 来阻止传递依赖项使用外来来源。
可信来源#
可信来源对于直接依赖和传递依赖都被认为是安全的。
npm 源#
pnpm add package-name 默认会从 npm 源安装 package-name 的最新版本。
如果在工作空间中执行,该命令将首先去检查这个工作空间中的其他项目是否已经使用了这个指定的包。如果是,已经使用过的版本范围将被安装。
你还可以通过以下方式安装包:
- 标签:
pnpm add express@nightly - 版本:
pnpm addexpress@1.0.0 - 版本范围:
pnpm add express@2 react@">=0.1.0 <0.2.0"
JSR 源#
添加于:v10.9.0
使用 jsr: 协议前缀从JSR 注册源安装:
pnpm add jsr:@hono/hono
pnpm add jsr:@hono/hono@4
pnpm add jsr:@hono/hono@latest
这和从 npm 安装的方式类似,只是告诉 pnpm 通过 JSR 解析包。
命名注册源#
添加于:v11.1.0
命名注册源 别名会针对特定注册源解析包,而不管默认注册源是什么:
pnpm add work:@corp/lib@^2.0.0
pnpm add gh:@my-org/private-pkg
pnpm add npmjs:left-pad
gh: (GitHub Packages) 以及 npmjs: (公共 npm 注册源) 自 v11.20.0 起无需任何配置即可使用。任何其他别名都必须映射到 pnpm-workspace.yaml 中的 namedRegistries 下,或者自 v11.11.0 起,映射到全局配置文件(config.yaml)中。
工作空间(Workspace)#
请注意,当添加依赖项并在 工作区 中工作时,软件包
将从配置的源安装,具体取决于是否设置了 linkWorkspacePackages,以及是否使用了 workspace: 范围协议。
本地文件系统#
有两种方法可以从本地文件系统安装:
- 从 tar 压缩包文件(
.tar、.tar.gz或.tgz) - 从目录
示例:
pnpm add ./package.tar.gz
pnpm add ./some-directory
当你从目录安装时,会在当前项目的node_modules 目录中生成一个符号链接,因此这和执行 pnpm link 一致。
外来来源#
外来来源对开发很有用,但当被传递依赖关系使用时,可能会带来供应链风险。
远程 tarball#
参数必须是一个可访问的 URL,以 "http://" 或 "https://" 开头。
示例:
pnpm add https://github.com/indexzero/forever/tarball/v0.5.6
Git 仓库#
pnpm add <git remote url>
从给定 URL 处的 Git 仓库安装该包。视仓库而定,pnpm 要么从 Git 托管方下载源码归档,要么用 Git 克隆仓库 — 参见 Git 依赖如何解析。
你可以通过以下方式从 Git 安装软件包:
- 来自默认分支的最新提交:
pnpm add kevva/is-positive
- Git 提交哈希:
pnpm add kevva/is-positive#97edff6f525f192a3f83cea1944765f769ae2678
- Git 分支:
pnpm add kevva/is-positive#master
- 相对于 refs 的 Git 分支:
pnpm add zkochan/is-negative#heads/canary
- Git 标签:
pnpm add zkochan/is-negative#2.0.1
- v 前缀的 Git 标签:
pnpm add andreineculau/npm-publish-git#v0.0.7
使用语义版本从 Git 存储库安装#
你可以使用 semver: 参数指定要安装的版本(范围)。例如:
- 严格的语义版本:
pnpm add zkochan/is-negative#semver:1.0.0
- v 前缀的严格语义版本:
pnpm add andreineculau/npm-publish-git#semver:v0.0.7
- 语义版本范围:
pnpm add kevva/is-positive#semver:^2.0.0
- v 前缀的语义版本范围:
pnpm add andreineculau/npm-publish-git#semver:<=v0.0.7
从 Git 存储库的子目录安装#
你也可以使用 path: 参数从 Git 托管的 monorepo 中仅安装子目录。例如:
pnpm add RexSkz/test-git-subfolder-fetch#path:/packages/simple-react-app
通过完整 URL 从 Git 存储库安装#
如果你想要更明确或使用其他 Git 托管,你可能需要拼出完整的 Git URL:
# git+ssh
pnpm add git+ssh://git@github.com:zkochan/is-negative.git#2.0.1
# https
pnpm add https://github.com/zkochan/is-negative.git#2.0.1
使用托管提供商简写从 Git 存储库安装#
你可以使用协议简写 [provider]: 来表示某些 Git 提供商:
pnpm add github:zkochan/is-negative
pnpm add bitbucket:pnpmjs/git-resolver
pnpm add gitlab:pnpm/git-resolver
如果省略 [provider]:,则默认为 github:。
结合不同参数从 Git 存储库安装#
可以通过用 & 分隔来组合多个参数。这对于 monorepo 的分叉是有用的:
pnpm add RexSkz/test-git-subdir-fetch.git#beta\&path:/packages/simple-react-app
从beta 分支安装,并仅安装 /packages/simple-react-app 子目录。
Git 依赖如何解析#
添加于:v12.0.0(pnpm v12 专用)
对于 GitHub、GitLab 和 Bitbucket 上的仓库,该说明符是一个身份标识,而不是传输方式的选择。以下所有写法命名的都是同一个依赖,并且解析结果完全相同:
kevva/is-positive
github:kevva/is-positive
git+https://github.com/kevva/is-positive.git
git+ssh://git@github.com/kevva/is-positive.git
每种写法都通过托管方的规范 HTTPS URL 解析,锁文件会记录以下两种形式之一:
- 托管方的源码归档,即普通的 tarball 下载。只有当针对该归档 URL 的匿名请求成功时才会记录这种形式,因此被记录的归档 URL 按其构造方式总是可获取的。
- 否则记录基于规范 HTTPS URL 的
git解析,任何能访问该仓库的机器都可以获取它。
pnpm 从不为这些托管方记录 SSH URL。某台机器使用哪种传输方式访问主机,属于该机器的 Git 配置,而非项目的属性。
pnpm 11 会把说明符的传输方式作为记录 URL 的一部分保留,但自 v11.21.0 起,只有当说明符本身要求时才记录 SSH URL(git+ssh:// 或 git@host:...):像 owner/repo 这样的简写会通过 HTTPS 解析并记录,因此在有 SSH 密钥的机器上写出的锁文件,仍可在没有密钥的 CI 运行器上安装。由旧版 pnpm 记录的 SSH URL 可通过 pnpm update <package> 重新以 HTTPS 记录。
为私有仓库使用 SSH#
在机器上的 Git 自身中配置改写:
git config --global url."git@github.com:".insteadOf https://github.com/
pnpm 会调用外部 git,因此该改写会自动作用于 pnpm 的所有 Git 操作。在 CI 上同理:给运行器提供 SSH 密钥并配置此改写,或提供一个 HTTPS 凭据助手 — 两种方式得到的锁文件完全相同。
其他主机上的仓库#
未指向已知主机的 URL(自建 GitLab、Gitea 或任何内部 Git 服务器)会按原样保留,包括其传输方式 — 对它们而言,URL 就是身份。内嵌凭据的 URL 同样会原样保留,并且绝不会解析为主机归档。
提示
在 pnpm v11 及更早版本中,解析过程会探测网络,以在 HTTPS 与 SSH 之间做出选择。这可能会记录下恰好在那台执行安装的机器上可用的传输方式 — 最常见的是 ssh:// URL,随后在没有 SSH 密钥的 CI 运行器上就会失败。 pnpm v12 移除了该探测。现有的锁文件条目保持不变;上述规则适用于新增或重新解析条目时。
Git 依赖如何构建#
新增于:v12.0.0-rc.6(仅限 pnpm v12)
若 Git 托管依赖提供的是源码而非已构建的包,则在安装前必须先完成准备 — 安装其依赖并运行其构建脚本。 pnpm 会用该依赖自身要求的包管理器来准备它,而不是假定主机上有正确的包管理器:
- 该依赖自身的
packageManager/devEngines.packageManager固定值优先 — 因为那是其作者测试时使用的版本; - 若没有固定值,则由它附带的锁文件指明包管理器。
yarn.lock还会指明是哪一条 Yarn 产品线:Yarn Berry 会把它写入的每个锁文件都标记上__metadata:,两条产品线都无法读取对方的锁文件,因此 Classic 的锁文件不会再由 Berry 安装。
当该依赖固定了版本,或主机无法满足该依赖所需时,pnpm 会提供该包管理器。因此,用 Yarn 构建的仓库可以在仅有 pnpm 的机器上安装;而已经具备合适包管理器的主机 — 在构建可能调用的所有名称下 — 仍会使用自己的包管理器。