Agent Skills: use-pnpm

>-

UncategorizedID: ruan-cat/monorepo/use-pnpm

Install this agent skill to your local

pnpm dlx add-skill https://github.com/ruan-cat/monorepo/tree/HEAD/ai-plugins/common-tools/skills/use-pnpm

Skill Files

Browse the full folder contents for use-pnpm.

Download Skill

Loading file tree…

ai-plugins/common-tools/skills/use-pnpm/SKILL.md

Skill Metadata

Name
use-pnpm
Description
>-

use-pnpm

Overview

本技能用于处理 pnpm 相关的安装、更新、工作区命令替换、Windows/PowerShell 故障和全局包恢复。重点覆盖 ERR_PNPM_UNEXPECTED_VIRTUAL_STOREPNPM_HOME 与全局依赖树错位、Corepack 管理 pnpm、NVM Desktop 切换 Node 后的 pnpm 运行时混乱。

目标不是复述事故过程,而是给 future-agent 一套可执行判断路径:先识别 pnpm 由谁管理、全局区在哪里、store 在哪里、虚拟 store 指向哪里,再决定是重建依赖树、修配置,还是切回正确的 Node/pnpm 管理链路。

When to Use

  • 用户要求安装、更新、删除、重建 pnpm 依赖或全局包。
  • 用户想把 npmnpxyarn 命令替换为 pnpm 写法。
  • pnpm 报错包含 ERR_PNPM_UNEXPECTED_VIRTUAL_STOREvirtual-store-dirstore-dirPNPM_HOME、global root、global bin 等关键词。
  • Windows 或 PowerShell 下 pnpm 命令异常、全局命令找不到、全局包升级失败。
  • Corepack 管理 pnpm,或 NVM Desktop 切换 Node 后 pnpm 版本、路径、全局区不一致。
  • pnpm workspace 中需要判断命令应该在根目录、子包目录,还是通过 --filter 执行。

When Not to Use

  • 任务与 pnpm 无关,只是通用 Node.js、TypeScript、Git 或框架问题。
  • 用户明确要求使用其他包管理器,并且没有迁移到 pnpm 的上下文。
  • 当前项目没有 pnpm 配置,也没有用户要求引入 pnpm。不要主动改包管理器。
  • 只是解释 JavaScript 语法、Node API 或业务代码逻辑,不涉及依赖管理。

Core Model

处理 pnpm 故障前必须区分这些概念:

  • PNPM_HOME:pnpm 放置全局可执行入口的位置,通常应出现在 PATH 中。它不是全局依赖真实安装树,也不是 store。
  • pnpm root -g:全局包的 node_modules 根目录,即全局依赖树所在位置,可称为 <pnpm-global-node-modules>;它的父目录才是全局区目录,通常包含 global package.jsonpnpm-lock.yaml
  • pnpm bin -g:全局命令 shim/bin 所在目录,可能等于或接近 PNPM_HOME,但必须用命令确认。
  • store-dir / pnpm store path:pnpm 内容寻址 store,保存包内容缓存,可称为 <store-dir>
  • virtual-store-dir:项目或全局依赖树内部的虚拟 store 目录,默认通常是 node_modules/.pnpm。它描述依赖树布局,不等于 store-dir

判断原则:

  1. store-dir 是包内容缓存,virtual-store-dir 是某个依赖树里的链接布局目录。
  2. ERR_PNPM_UNEXPECTED_VIRTUAL_STORE 通常说明现有 node_modules.modules.yaml 记录和当前 pnpm 期望的 virtual store 位置不一致。
  3. 如果错误发生在 pnpm add -gpnpm update -gpnpm i -g、全局命令升级或全局包列表操作中,先按 global 场景处理。
  4. global 场景优先重建全局依赖树,不要第一反应就改全局 .npmrc 或全局 pnpm 配置。

First Checks

在 Windows/PowerShell 中先收集这些证据:

where.exe node
where.exe pnpm
where.exe corepack
node -v
pnpm -v
corepack --version
pnpm config get global-dir
pnpm config get store-dir
pnpm config get virtual-store-dir
pnpm store path
pnpm root -g
pnpm bin -g

如果是项目内问题,再补充:

pnpm config list
pnpm config list --location project
pnpm config list --location global

pnpm install --lockfile-only 可能写入 pnpm-lock.yaml。该命令仅在用户允许更新锁文件或需要验证锁文件解析时执行,不要把它当作纯只读证据收集命令。

检查 node_modules/.modules.yaml 时,只读取关键字段:storeDirvirtualStoreDirlayoutVersionpackageManager。不要把整个文件当作需要手写修复的配置文件。

Decision Path

  1. 判断 pnpm 是谁管理的:

    • corepack pnpm --version 可用且项目依赖 Corepack:优先按 Corepack 管理。
    • where.exe pnpm 指向某个 Node 安装或 Corepack shim:继续检查 where.exe node 和版本。
    • pnpm 来自独立安装器或系统包管理器:按对应安装源处理,不混用 npm 全局安装。
  2. 判断错误范围:

    • -g 或涉及全局命令:global 场景。
    • 在项目根目录或子包中执行 pnpm install:project/workspace 场景。
    • 只有某个包脚本失败:先确认脚本是否实际调用 pnpm 或读取 pnpm 路径。
  3. 判断是否是 virtual store 错位:

    • 错误包含 ERR_PNPM_UNEXPECTED_VIRTUAL_STORE
    • .modules.yaml 中的 virtualStoreDir 与当前配置或当前路径不一致。
    • 切换 Node、pnpm 版本、配置或迁移目录后出现。
  4. 选择恢复策略:

    • global 场景:备份全局依赖树元数据,重建 global 区。
    • project 场景:优先删除并重建当前项目的 node_modules,不要改全局配置绕过。
    • 配置污染场景:移除不合理的全局 virtual-store-dir,必要时在项目级写相对路径并说明原因。

Windows Global Virtual Store Recovery

遇到全局 ERR_PNPM_UNEXPECTED_VIRTUAL_STORE 时按这个顺序处理。

先备份全局元数据:

$globalNodeModules = pnpm root -g
$globalDir = Split-Path -Parent $globalNodeModules
Copy-Item -LiteralPath "$globalDir\package.json" -Destination "$globalDir\package.json.bak" -ErrorAction SilentlyContinue
Copy-Item -LiteralPath "$globalDir\pnpm-lock.yaml" -Destination "$globalDir\pnpm-lock.yaml.bak" -ErrorAction SilentlyContinue
Copy-Item -LiteralPath "$globalNodeModules\.modules.yaml" -Destination "$globalDir\.modules.yaml.bak" -ErrorAction SilentlyContinue

再重建全局依赖树:

pnpm i -g

如果当前环境无 TTY,且 pnpm i -g 因交互提示无法继续,可以只对这一次命令临时设置 CI=true

$hadCI = Test-Path Env:CI
$previousCI = $env:CI
try {
  $env:CI = "true"
  pnpm i -g
}
finally {
  if ($hadCI) {
    $env:CI = $previousCI
  }
  else {
    Remove-Item Env:CI -ErrorAction SilentlyContinue
  }
}

如果仍失败,再检查:

pnpm config get virtual-store-dir
pnpm config list --location global
pnpm root -g
pnpm store path

不要把绝对 virtual-store-dir 写进全局 .npmrc 或全局 pnpm 配置来压住错误。绝对 virtual store 会把不同 Node、不同用户、不同全局区耦合到同一个布局路径,后续切 Node 或迁移目录时更容易复发。

NVM Desktop + Corepack Rules

Windows + NVM Desktop + Corepack 的核心风险是:nodecorepackpnpm 可能来自不同 Node 版本或不同 shim 目录。切 Node 或换 pnpm 版本后,先验证路径和版本,再重建 global 区。

必查命令:

where.exe node
where.exe pnpm
where.exe corepack
node -v
pnpm -v
corepack --version
pnpm root -g
pnpm bin -g
pnpm store path
pnpm config get global-dir
pnpm config get store-dir
pnpm config get virtual-store-dir

规则:

  • 如果项目使用 Corepack 管 pnpm,不要把 npm i -g pnpmpnpm add -g pnpm 当作升级 pnpm 本体的首选方式。
  • Corepack 管理时,优先使用 Corepack 激活或准备目标 pnpm 版本;如果当前 pnpm 明确支持并且管理链路允许,也可以使用 pnpm self-update
  • 切换 Node 后,全局包区和 shim 可能需要重新安装或重建。先让 where.exe nodewhere.exe pnpmwhere.exe corepack 指向同一套预期链路,再运行 pnpm i -g
  • 不要混用多个来源安装 pnpm。出现多个 where.exe pnpm 结果时,先解释路径优先级,再决定清理哪一个。

Command Mapping

常见替换:

| npm/yarn/npx | pnpm | | ---------------------- | -------------------------------------- | | npm install | pnpm install | | npm install <pkg> | pnpm add <pkg> | | npm install -D <pkg> | pnpm add -D <pkg> | | npm uninstall <pkg> | pnpm remove <pkg> | | npm update <pkg> | pnpm update <pkg> | | npm run <script> | pnpm run <script>pnpm <script> | | npx <bin> | pnpm dlx <bin> | | yarn add <pkg> | pnpm add <pkg> | | yarn remove <pkg> | pnpm remove <pkg> | | yarn why <pkg> | pnpm why <pkg> |

全局命令:

pnpm add -g <pkg>
pnpm update -g <pkg>
pnpm remove -g <pkg>
pnpm list -g --depth 0

注意:pnpm add -g pnpm 不是 Corepack 场景下升级 pnpm 本体的默认答案。先确认 pnpm 管理方式。

Workspace Rules

  • 先确认当前目录是否是 workspace 根目录,是否存在 pnpm-workspace.yaml
  • 在根目录给 workspace 添加依赖时,明确目标包:
pnpm --filter <package-name> add <dependency>
pnpm --filter <package-name> add -D <dependency>
  • 根包确实需要依赖时,使用 -w
pnpm add -w -D <dependency>
  • 执行脚本时优先用 --filter 精确约束范围:
pnpm --filter <package-name> build
pnpm --filter <package-name> test
  • 不确定目标包时先问用户,或读取 workspace 清单和相关 package.json。不要在 workspace 根目录随意安装运行时依赖。
  • 不要把某个项目的 virtual-store-dir 经验泛化到整个 workspace。确实需要自定义时,只允许项目级相对路径,例如:
virtual-store-dir=.pnpm

并说明为什么默认 node_modules/.pnpm 不适用。

Safety Rules

  • 修复前备份 global-dir 下的 package.jsonpnpm-lock.yaml,以及 pnpm root -g 返回目录下的 .modules.yaml
  • 不要手写大段 .modules.yaml 内容;它是 pnpm 生成的状态文件,优先通过重建依赖树恢复。
  • 不建议把绝对 virtual-store-dir 写入全局 .npmrc 或全局 pnpm 配置。
  • 如果项目确实需要 virtual-store-dir,只使用项目级相对路径,并写清原因。
  • 不要同时使用 npm 全局安装、Corepack、pnpm self-update 管理同一个 pnpm 本体。
  • Windows 下优先使用 where.exe 检查真实命令解析,避免 PowerShell alias 或 shim 混淆。
  • 删除 node_modules 或全局依赖树前,先确认路径是 <project-root>\node_modulespnpm root -g 返回的全局 node_modules,不要对模糊变量做递归删除。
  • 无 TTY 环境下如需跳过交互,只对单次 pnpm i -g 临时设置 CI=true,不要长期污染 shell 环境。

Verification Checklist

修复完成后至少验证:

pnpm list -g --depth 0
pnpm root -g
pnpm bin -g
pnpm store path
pnpm config get virtual-store-dir

然后重跑原失败命令。例如:

pnpm add -g <pkg>
pnpm update -g <pkg>
<original-failing-command>

闭环标准:

  • pnpm list -g --depth 0 能列出全局包。
  • 原失败命令不再报 ERR_PNPM_UNEXPECTED_VIRTUAL_STORE
  • PNPM_HOMEpnpm bin -gpnpm root -gpnpm store path 能解释清楚且互不混淆。
  • 全局配置里没有不合理的绝对 virtual-store-dir
  • 如果改了项目级配置,配置是相对路径且原因已写明。

Common Mistakes

  • store-dir 当成 virtual-store-dir,或把 pnpm store path 当成全局依赖安装目录。
  • pnpm root -g 当成 global-dir;它返回的是全局 node_modules,global package.jsonpnpm-lock.yaml 在它的父目录。
  • 看到 ERR_PNPM_UNEXPECTED_VIRTUAL_STORE 就先改全局 virtual-store-dir
  • 在 Corepack 管理 pnpm 时用 npm i -g pnpm 覆盖 shim,导致 where.exe pnpm 指向混乱。
  • NVM Desktop 切 Node 后只看 node -v,不看 where.exe nodewhere.exe pnpmwhere.exe corepack
  • 不备份 global 元数据就删除全局依赖树。
  • 在无 TTY 环境永久设置 CI=true,影响后续命令行为。
  • 在 workspace 根目录不带 --filter-w 直接加依赖。
  • 把某台机器的绝对路径写进可分发技能文档、项目模板或全局配置。

Future Expansion

这个技能应保持简单、长期可扩展:

  • 新增 pnpm 规范、事故提炼、平台差异说明时,优先放入 references/,正文只保留稳定决策路径。
  • 只有当存在可复用、确定性的检查逻辑时,才新增 scripts/fallback/
  • 新增脚本时必须以技能安装目录为运行视角,不依赖安装目录之外的位置。
  • 扩展内容不得引用不可迁移的内部证据、个人信息、机器专属绝对路径或环境专属流程路径。
  • 对外分发内容只写可迁移规则、占位路径和可验证命令。