Files
2026-07-13 21:35:53 +08:00

3.7 KiB
Raw Permalink Blame History

name, description
name description
pnpm-store pnpm 的内容可寻址存储系统,使其安装速度快且磁盘占用低

pnpm 存储

pnpm 使用内容可寻址存储来节省磁盘空间并加速安装。所有包仅全局存储一次,并通过硬链接映射到项目的 node_modules

工作原理

  1. 全局存储:包只下载一次,存入中央存储
  2. 硬链接:项目通过链接引用存储,而非复制文件
  3. 内容可寻址:文件按内容哈希存储,相同文件自动去重

存储布局

~/.pnpm-store/              # 全局存储(默认位置)
└── v3/
    └── files/
        └── <hash>/         # 按内容哈希存储的文件

project/
└── node_modules/
    ├── .pnpm/              # 虚拟存储(到全局存储的硬链接)
    │   ├── lodash@4.17.21/
    │   │   └── node_modules/
    │   │       └── lodash/
    │   └── express@4.18.2/
    │       └── node_modules/
    │           ├── express/
    │           └── <deps>/  # 依赖的扁平结构
    ├── lodash -> .pnpm/lodash@4.17.21/node_modules/lodash
    └── express -> .pnpm/express@4.18.2/node_modules/express

存储命令

# 显示存储位置
pnpm store path

# 移除未被引用的包
pnpm store prune

# 检查存储完整性
pnpm store status

# 将包添加到存储而不安装
pnpm store add <pkg>

配置

存储位置

# .npmrc
store-dir=~/.pnpm-store

# 或使用环境变量
PNPM_HOME=~/.local/share/pnpm

虚拟存储

虚拟存储(node_modules 中的 .pnpm 目录)包含指向全局存储的符号链接:

# 自定义虚拟存储位置
virtual-store-dir=node_modules/.pnpm

# 替代的扁平布局
node-linker=hoisted

磁盘空间优势

pnpm 可显著节省磁盘空间:

  • 去重:同一包版本在所有项目中只存储一次
  • 内容去重:不同包中的相同文件只存储一次
  • 硬链接:无需复制,仅需链接

检查磁盘占用

# 比较实际大小与表观大小
du -sh node_modules        # 表观大小
du -sh --apparent-size node_modules  # 包含硬链接计数

Node Linker 模式

配置 node_modules 的结构:

# 默认:符号链接结构(推荐)
node-linker=isolated

# 扁平的 node_modules(类似 npm,用于兼容)
node-linker=hoisted

# PnP 模式(实验性,类似 Yarn PnP)
node-linker=pnp

隔离模式(默认)

  • 严格的依赖解析
  • 无幻影依赖
  • 包只能访问已声明的依赖

提升模式

  • 类似 npm 的扁平 node_modules
  • 用于兼容不支持符号链接的工具
  • 失去严格性优势

副作用缓存

缓存原生模块的构建输出:

# 启用副作用缓存
side-effects-cache=true

# 将副作用存储在项目中(而非全局存储)
side-effects-cache-readonly=true

跨机器共享存储

在 CI/CD 中可以共享存储:

# GitHub Actions 示例
- uses: pnpm/action-setup@v4
  with:
    run_install: false

- name: 获取 pnpm 存储目录
  shell: bash
  run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV

- uses: actions/cache@v4
  with:
    path: ${{ env.STORE_PATH }}
    key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}

故障排除

存储损坏

# 验证并修复存储
pnpm store status
pnpm store prune

硬链接问题(网络驱动器、Docker

# 使用复制而非硬链接
package-import-method=copy

权限问题

# 修复存储权限
chmod -R u+w ~/.pnpm-store