全局软件包

全局软件包是使用 pnpm add -g 安装到系统范围内的 CLI 工具和实用程序。在 pnpm v11 中,全局包管理被重新设计,以提升隔离性和可靠性。

安装全局软件包#

pnpm add -g <pkg>

例如:

pnpm add -g typescript prettier eslint

注意

不要通过 sudo 运行这些命令。 pnpm keeps global packages and configuration in the invoking user's home directory, so under sudo they operate on the root user's home instead of yours. Since v11.21.0, pnpm setup, pnpm self-update, and every command that modifies the global installation print a warning when run as root. 诸如 pnpm bin -g 之类的只读命令不受影响。

独立安装#

每个全局安装的软件包(或一起安装的一组软件包)都有其自己的独立安装目录,其中包含自己的 package.json、node_modules/ 和锁文件。这样可以阻止全局包之间因对等依赖冲突、提升更改或版本错位而相互干扰。

隔离安装存储在 {pnpmHomeDir}/global/v11/{hash}/,其中哈希值是从一起安装的软件包集合中派生出来的。

例如,运行以下两个命令:

pnpm add -g typescript
pnpm add -g prettier

creates two separate isolated installations. typescript and prettier each get their own node_modules tree and cannot affect each other's dependency resolution.

在单个命令中安装多个空格分隔 软件包也会为每个软件包单独创建一个单独的安装:

pnpm add -g eslint prettier

eslint and prettier each get their own node_modules tree and lockfile and can be removed independently. pnpm remove -g eslint leaves prettier untouched.

To bundle multiple packages into the same isolated install (so they share a node_modules tree and lockfile, resolve peer dependencies against each other, and are removed together), pass them as a comma-separated list:

pnpm add -g eslint,prettier

这里的 eslint 和 prettier 形成了一个安装组。使用 pnpm remove -g 删除任一项都会删除整个组。

pnpm add -g <pkg> replaces every existing group that contains <pkg>. After pnpm add -g eslint, the eslint,prettier group is gone, and so are prettier and its bins. To keep the group, add it again as a whole (pnpm add -g eslint,prettier), or use pnpm update -g.

这两种形式可以混合使用。例如:

pnpm add -g eslint,prettier typescript

将 eslint 和 prettier 打包为一次孤立安装,同时单独安装 typescript。

目录布局#

{pnpmHomeDir}/global/v11/ 的内容如下所示:

{pnpmHomeDir}/global/v11/
├── {hash-A}              → symlink → ./{hash-A-target}/
├── {hash-A-target}/      ← isolated install dir
│   ├── package.json      ← lists the packages installed together
│   ├── pnpm-lock.yaml    ← lockfile for this install group
│   └── node_modules/
│       ├── <pkg>/        ← top-level dep, symlinked into the global virtual store
│       └── .pnpm/        ← the group's install state
├── {hash-B}              → symlink → ./{hash-B-target}/
└── {hash-B-target}/      ← another isolated install dir
  • {hash} 条目是符号链接;pnpm 会扫描它们以枚举活动的安装。
  • The targets are real directories that act as ordinary pnpm projects. Each has its own package.json and lockfile.
  • By default, the package contents live in the global virtual store at {storeDir}/links, outside this directory. Each install group's direct dependencies (the entries at the root of its node_modules/) are symlinks into that store, so install groups that depend on the same package share one copy. With virtualStoreType: project, each install group keeps its packages in its own node_modules/.pnpm.
  • 二进制 shims 位于 {pnpmHomeDir}/bin/ 中,并指向相应的安装组的 node_modules。

When a package is removed or its install group is replaced, the hash symlink is updated. Orphaned target directories older than five minutes are removed at the start of the next pnpm add -g, pnpm update -g, or pnpm self-update.

列出全局软件包#

pnpm list -g
pnpm list -g --json # 机器可读
pnpm list -g --parseable # 仅路径

Because each install group has its own lockfile, listing across multiple groups can only reliably aggregate the top-level packages they were installed with. Transitive dependency trees from different groups can't be coherently merged. 因此:

  • pnpm list -g(默认 --depth=0)始终有效,并显示所有全局安装的软件包。
  • pnpm list -g --depth=<n>(其中 n > 0)仅在以下情况下显示完整的依赖关系树:
    • 只有一个全局安装组,或者
    • 位置参数将请求范围缩小到单个安装组,例如 pnpm list -g eslint --depth=1。

如果请求 --depth>0 但无法将请求缩小到单个安装组,pnpm 将报错 ERR_PNPM_GLOBAL_LS_DEPTH_NOT_SUPPORTED。

管理全局软件包#

命令 描述
pnpm add -g <pkg> 全局安装软件包
pnpm remove -g <pkg> 移除一个全局安装的软件包(如果该软件包被打包在某个安装组中,则整个组将被移除)
pnpm update -g [pkg] Update global packages (re-installs a package into a new isolated directory when its resolved dependency graph changed)
pnpm list -g 列出所有全局安装的软件包

注意

不再支持 pnpm install -g (无参数)。使用 pnpm add -g <pkg> 安装特定软件包。

二进制文件位置#

全局安装的二进制文件存储在 PNPM_HOME 的 bin 子目录中(即 $PNPM_HOME/bin/)。 This keeps the PNPM_HOME directory clean. Internal directories like global/ and store/ don't pollute shell autocompletion when PNPM_HOME is on PATH.

升级到 pnpm v11 后,运行 pnpm setup 来更新你的 shell 配置,以便 $PNPM_HOME/bin 在你的 PATH 中。

你可以通过以下方式检查当前的全局 bin 目录:

pnpm bin -g

全局虚拟存储#

全局安装使用全局虚拟存储。软件包存储在 {storeDir}/links 中,并在全局安装之间共享。这样可以避免多个全局包依赖于相同库时进行冗余获取。

全局注册本地软件包#

要使本地软件包的二进制文件在系统范围内可用,请在软件包目录中使用 pnpm add -g . 命令:

cd ~/projects/my-tool
pnpm add -g .

这样就注册了软件包的 bin 条目,以便可以从任何地方调用它们。请参阅 pnpm link 了解更多详情。

构建脚本批准#

包含构建脚本(例如 postinstall)的全局软件包需要获得批准。当你安装需要运行构建脚本的全局软件包时,pnpm 会提示你以交互方式批准或拒绝构建。

你还可以使用 --allow-build 标志预先批准构建:

pnpm add -g --allow-build=esbuild esbuild

Since v11.24.0, pnpm approve-builds --global lets you decide after the fact instead. It collects the packages awaiting approval from every install group, asks about them once, and writes one allowBuilds policy into the pnpm-workspace.yaml of the global packages directory, then rebuilds only the groups that contain something you approved:

pnpm approve-builds -g