pnpm:快速、节省空间的 Node.js 包管理器

前言

本文将介绍 pnpm 的核心优势、与 npm/yarn 的对比,以及详细的安装、配置和使用指南。

为什么需要另一个包管理器?

在 Node.js 生态中,npm 是默认的包管理器,但随着项目规模增长,你可能会遇到:

  • 安装速度慢:每次 npm install 都要下载大量重复文件
  • 磁盘空间占用大:每个项目都有独立的 node_modules,大量重复依赖
  • 依赖安全问题:幽灵依赖(Phantom dependencies)和 NPM doppelgangerspnpm 正是为解决这些问题而生。

pnpm 是什么?

pnpm(Performance NPM)是一个快速、节省空间的 Node.js 包管理器,由 Zoltan Kochan 开发。它的核心创新在于使用内容寻址存储和硬链接机制。

核心特性

1.速度快:并行安装,支持增量更新

2.节省空间:所有项目共享同一个存储,使用硬链接

3.严格依赖:避免幽灵依赖

4.安全性高:无法访问未声明的包

pnpm vs npm vs yarn

特性 npm yarn pnpm

安装速度 慢 中等 最快

磁盘占用 最大 中等 最小

依赖严格性 宽松 宽松 严格

锁文件 package-lock.json yarn.lock pnpm-lock.yaml

Monorepo支持 一般 良好 优秀

工作区 支持 支持 原生支持

性能对比实测

bash 复制代码
# 测试项目:100+依赖
npm install # 45秒
yarn install   # 28秒
pnpm install   # 12秒⭐

# 磁盘占用npm: 850MB (每个项目)
yarn:   600MB (每个项目)
pnpm:   150MB (共享存储) ⭐

pnpm 的工作原理

传统 npm 的问题

text 复制代码
project-a/
  node_modules/
    package-a/  # 10MB
    package-b/  # 5MB

project-b/
  node_modules/
    package-a/  # 10MB (重复)
    package-b/  # 5MB (重复)

pnpm 的解决方案

text 复制代码
全局存储 (~/.pnpm-store/)
  ├── package-a@1.0.0/  # 10MB
  ├── package-b@1.0.0/  # 5MB
  └── ...

project-a/
  node_modules/
    package-a -> ../../.pnpm-store/package-a@1.0.0 (硬链接)
    package-b -> ../../.pnpm-store/package-b@1.0.0

project-b/
  node_modules/
    package-a -> ../../.pnpm-store/package-a@1.0.0 (硬链接)
    package-b -> ../../.pnpm-store/package-b@1.0.0

优势:

10个项目共享相同依赖,磁盘占用 = 1个项目- 硬链接不占用额外空间

符号链接确保正确的依赖解析

安装 pnpm

方式1:npm安装(推荐)

bash 复制代码
npm install -g pnpm

方式2:独立安装脚本

bash 复制代码
# Linux/macOS
curl -fsSL https://get.pnpm.io/install.sh | sh -

# Windows (PowerShell)
iwr https://get.pnpm.io/install.ps1 -useb | iex

方式3:使用 Node.js 内置 corepack(Node.js 16.9+)

bash 复制代码
corepack enable
corepack prepare pnpm@latest --activate

验证安装

bash

bash 复制代码
pnpm --version
# 输出:8.x.x 或更高

基本使用

  1. 初始化项目
bash 复制代码
# 创建新项目
mkdir my-project && cd my-project
pnpm init

# 结果:生成 package.json
  1. 安装依赖
bash 复制代码
# 安装所有依赖(推荐)
pnpm install

# 安装特定包
pnpm add lodash

# 安装开发依赖
pnpm add -D typescript

# 安装生产依赖
pnpm add --save-prod express

# 全局安装
pnpm add -g @vue/cli
  1. 运行脚本
bash 复制代码
# package.json
{
  "scripts": {
    "dev": "vite",
    "build": "vite build"
  }
}

# 运行
pnpm run dev
# 或简写
pnpm dev
  1. 其他常用命令
bash 复制代码
# 更新依赖
pnpm update

# 移除依赖
pnpm remove lodash

# 查看依赖树
pnpm list

# 查看过时的包
pnpm outdated

# 清理未使用的包
pnpm prune

# 查看磁盘使用情况
pnpm store status

配置镜像源

  1. 查看当前配置
bash 复制代码
pnpm config get registry
# 默认:https://registry.npmjs.org/
  1. 设置淘宝镜像(推荐国内用户)
bash 复制代码
# 方法一:使用新淘宝镜像(推荐)
pnpm config set registry https://registry.npmmirror.com

# 方法二:使用旧淘宝镜像(可能已过期)
pnpm config set registry https://registry.npm.taobao.org
  1. 设置华为云镜像
bash 复制代码
pnpm config set registry https://repo.huaweicloud.com/repository/npm/
  1. 设置腾讯云镜像
bash 复制代码
pnpm config set registry https://mirrors.cloud.tencent.com/npm/
  1. 临时使用镜像安装
bash 复制代码
pnpm --registry https://registry.npmmirror.com install
  1. 恢复官方源
bash 复制代码
# 方式一
pnpm config delete registry
# 方式二
pnpm config set registry https://registry.npmjs.org/
  1. 使用 .npmrc 配置文件

在项目根目录创建 .npmrc 文件:

ini 复制代码
# .npmrc
registry=https://registry.npmmirror.com

# 其他配置
strict-ssl=false # 如果证书有问题
save-exact=true           # 精确保存版本
shamefully-hoist=true     # 模拟npm的扁平化(不推荐)

高级配置

  1. 设置全局存储路径
bash 复制代码
# Linux/macOS
pnpm config set store-dir ~/.pnpm-store
# Windows
pnpm config set store-dir C:\Users\YourName\.pnpm-store
# 自定义路径
pnpm config set store-dir /usr/local/pnpm-store
  1. 设置全局bin目录
bash 复制代码
pnpm config set global-bin-dir ~/.pnpm-global/bin

# bash 
echo 'export PATH="$HOME/.pnpm-global/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc


# zsh
echo 'export PNPM_HOME="$HOME/.pnpm-global"' >> ~/.zshrc
echo 'export PATH="$PNPM_HOME:$PATH"' >> ~/.zshrc
source ~/.zshrc
  1. 配置网络代理
bash 复制代码
# 设置代理
pnpm config set proxy http://proxy.example.com:8080
pnpm config set https-proxy http://proxy.example.com:8080

# 删除代理
pnpm config delete proxy
pnpm config delete https-proxy
  1. 性能优化配置
bash 复制代码
# 并行安装(默认已启用)
pnpm config set concurrency 10

# 禁用锁文件(不推荐)
pnpm config set lockfile false

# 使用严格模式
pnpm config set strict-ssl true

Monorepo 支持

pnpm 对 Monorepo 有原生优秀支持:

  1. 初始化 Monorepo
bash 复制代码
mkdir my-monorepo && cd my-monorepo
pnpm init

# 创建 pnpm-workspace.yaml
echo 'packages:
  - packages/*
  - apps/*' > pnpm-workspace.yaml
  1. 项目结构

text

text

my-monorepo/

├── pnpm-workspace.yaml

├── package.json

├── packages/

│ ├── shared/

│ │ └── package.json

│ └── component/

│ └── package.json

└── apps/

├── web/

└── mobile/

  1. 依赖共享
bash 复制代码
# 在根目录安装公共依赖
pnpm add -D -w typescript

# 在特定workspace安装
pnpm add lodash --filter @my-app/web
  1. 常用命令
bash 复制代码
# 在所有workspace执行命令
pnpm -r exec rm -rf node_modules

# 只在修改的workspace执行
pnpm -r --filter git-changed... run build

# 查看workspace依赖图
pnpm m list

pnpm 的独特功能

  1. 依赖覆盖(Overrides)
json 复制代码
// package.json
{
  "pnpm": {
    "overrides": {
      "lodash": "4.17.21",
      "react": "18.2.0"
    }
  }
}
  1. 仅允许某些版本
json 复制代码
{
  "pnpm": {
    "allowedVersions": {
      "react": "^18.0.0"
    }
  }
}
  1. 依赖补丁
bash 复制代码
# 创建补丁
pnpm patch package-name@1.0.0

# 应用补丁后
pnpm patch-commit <patch-dir>

最佳实践

  1. 项目配置
bash 复制代码
# 1. 安装pnpmnpm install -g pnpm

# 2. 配置镜像
pnpm config set registry https://registry.npmmirror.com

# 3. 创建项目
pnpm init

# 4. 安装依赖
pnpm add vue react

# 5. 提交到Git
git add package.json pnpm-lock.yaml
git commit -m "chore: add pnpm support"
  1. 团队协作

在项目中添加 .npmrc 文件:

ini 复制代码
# .npmrc
registry=https://registry.npmmirror.com
engine-strict=true       # 严格检查Node版本
package-manager-strict=true  # 严格检查包管理器

在 package.json 中指定引擎:

json 复制代码
{
  "engines": {
    "node": ">=16.0.0",
    "pnpm": ">=8.0.0"
  },
  "packageManager": "pnpm@8.15.0"
}
  1. CI/CD 集成
yaml 复制代码
# .github/workflows/ci.yml
name: CI
on: [push]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Setup pnpm
        uses: pnpm/action-setup@v2
        with:
          version: 8

      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'
          cache: 'pnpm'

      - name: Install dependencies
        run: pnpm install --frozen-lockfile

      - name: Build
        run: pnpm run build

常见问题

Q1: pnpm 会破坏我的项目吗?

A: 不会。pnpm 遵循 Node.js 模块解析规范,但更严格。如果你的项目依赖幽灵依赖,需要修复。

Q2: 如何迁移到 pnpm?

bash 复制代码
# 1. 备份 package-lock.json
cp package-lock.json package-lock.json.backup

# 2. 删除 node_modules
rm -rf node_modules

# 3. 安装pnpm
npm install -g pnpm

# 4. 安装依赖
pnpm install

# 5. 测试
pnpm run test

Q3: pnpm 与 npm 的兼容性如何?

A: 完全兼容。pnpm 使用标准的 package.json,可以与 npm/yarn 混用(但不推荐)。

Q4: 如何清理 pnpm 存储?

bash 复制代码
# 查看存储状态
pnpm store status

# 清理未使用的包
pnpm store prune

总结

pnpm 是一个现代化的包管理器,通过创新的存储机制解决了 npm 的主要痛点:

✅ 更快 - 并行安装,增量更新

✅ 更省空间 - 共享存储,硬链接

✅ 更安全 - 严格依赖,无幽灵依赖

✅ 更现代 - 优秀的 Monorepo 支持

快速开始

bash 复制代码
#1. 安装
npm install -g pnpm

# 2. 配置镜像
pnpm config set registry https://registry.npmmirror.com

# 3. 使用
pnpm init
pnpm add express
pnpm run dev

何时使用?

✅ 新项目:强烈推荐

✅ 大型项目:节省大量磁盘空间

✅ Monorepo:原生支持,体验最佳

✅ 团队协作:统一依赖管理

何时不使用?

❌ 遗留项目依赖幽灵依赖:需要先修复

❌ 团队强制要求 npm/yarn:需要协商

立即尝试 pnpm,享受更快的安装速度和更少的磁盘占用!


good day!!!

相关推荐
石小千2 小时前
Jenkins服务器上排查npm编译依赖包错误问题
服务器·npm·jenkins
程序员爱钓鱼2 小时前
Node.js 博客系统实战(一):项目需求分析
前端·后端·node.js
Jing_Rainbow16 小时前
【Vue-2/Lesson62(2025-12-10)】模块化与 Node.js HTTP 服务器开发详解🧩
前端·vue.js·node.js
TE-茶叶蛋17 小时前
NestJS中使用TypeORM
node.js
Drift_Dream19 小时前
Node.js 第3课:Express.js框架入门
node.js
c***69301 天前
node.js下载、安装、设置国内镜像源(永久)(Windows11)
node.js
全栈前端老曹1 天前
【包管理】npm init 项目名后底层发生了什么的完整逻辑
前端·javascript·npm·node.js·json·包管理·底层原理
callJJ1 天前
MCP配置与实战:深入理解现代开发工具链
javascript·node.js·vue·mcp·windsurf
程序员爱钓鱼1 天前
Node.js 编程实战:测试与调试 —— 日志与监控方案
前端·后端·node.js