一文了解 pnpm,并快速上手操作!

PNPM 简介

npm(Node Package Manager)中文名为 Node 包管理器,是 Node.js 官方自带、全球最大的 JavaScript 软件包管理工具,也是前端 / Node.js 开发最基础、最常用的工具之一。

pnpm(Performant NPM),翻译过来就是高性能的 npm,旨在解决传统包管理器(如 npm 和 Yarn Classic)在性能、磁盘空间使用和依赖管理结构上的不足。

目前,pnpm 已成为前端生态最受欢迎的包管理器之一,被 Vue、Vite、Nuxt、Next.js、Svelte 等顶级开源项目,以及字节、阿里、腾讯等大厂的前端团队广泛采用,是公认的「当前最先进的包管理工具」。

pnpm 比传统方案安装包的速度快了两倍,以下是官方给出的benchmarks(对比了npm, pnpm, Yarn Classic, and Yarn PnP),在多种常见情况下,执行install的速度比较

pnpm 的核心优势,源于它从底层架构上彻底重构了依赖管理方式,精准解决了传统工具的多个顽疾:

1. 解决"磁盘空间浪费"与"安装速度慢"

使用 npm 时,若你有 100 个项目都依赖同一个包,硬盘中就会重复存储 100 份该依赖包的完整副本,造成大量磁盘空间浪费。

pnpm 则通过硬链接 搭配符号链接(软链接) 的机制,从根源上避免依赖重复拷贝,同时大幅提升安装效率:

  1. 增量存储 :针对同一依赖包的不同版本,pnpm 仅会存储版本间存在差异的文件 。例如新版本仅修改了单个文件,pnpm update 只需新增这一个文件至存储仓库,无需完整保存整个依赖包。
  2. 全局共享 :pnpm 会在本地维护一个全局内容寻址存储库 (默认路径为 ~/.pnpm-store),所有项目用到的依赖包,在全局仓库仅留存一份真实物理文件。
  3. 零拷贝 :项目安装依赖时,pnpm 不会复制文件,而是通过硬链接 (项目里 /node_modules/.pnpm/)指向全局仓库中的源文件;
  4. 兼容结构 :最后通过软链接 搭建符合 Node.js 规范的 node_modules 根目录结构,让项目和构建工具能正常识别依赖,同时为依赖隔离打下基础。

2. 解决"幽灵依赖" (Phantom Dependencies)

幽灵依赖是 npm 体系中一个极具隐患的问题。npm 会通过依赖扁平化(Dependency Hoisting) 机制,将间接依赖提升至 node_modules 根目录,这就导致项目可以直接引入并使用那些并未在自身 package.json 中声明的依赖包。这类依赖之所以能被访问,只是因为它们是其他直接依赖的子依赖,并在依赖提升后暴露在了根目录下。

幽灵依赖看似能简化开发,实则暗藏风险:

  1. 依赖版本不可控,易造成构建结果不稳定,排查问题时需要逐层追溯依赖树,调试与维护成本极高;
  2. 不同环境下依赖结构可能存在差异,极易出现本地正常、线上构建失败的情况;
  3. 间接依赖若存在安全漏洞,开发者往往难以感知,会带来潜在的安全风险。

pnpm 则通过虚拟存储(Virtual Store) 机制,从底层解决这一痛点:

它在项目内模拟传统 node_modules 的嵌套结构,同时在 .pnpm 目录下以包名 + 版本号的形式为每个版本创建独立文件夹,通过硬链接从全局仓库精准关联对应版本的真实文件;

再通过根目录node_modules 的符号链接,构建出严格的依赖隔离层级。

最终实现不同版本的依赖独立存放、精准引用、互不干扰,从根源上杜绝版本冲突,完美支持 Monorepo 场景下多子包的不同版本依赖,保障复杂依赖关系下项目的稳定运行。

3. 解决"多版本依赖冲突"

在实际项目中,常会出现不同第三方库依赖同一依赖包不同版本的情况(如部分组件库依赖 React 17,另一部分依赖 React 18)。

npm 针对该问题采用嵌套 node_modules 的基础隔离方案,将不兼容的版本安装在对应第三方包的内部目录中。但此方案存在明显缺陷:依赖目录结构变得杂乱无章,Windows 系统下易因路径过长导致报错,大量重复嵌套的依赖会造成磁盘空间浪费;加之 npm 保留的扁平化逻辑无法实现严格隔离,版本冲突与项目运行异常的风险始终存在。

pnpm 使用了一种叫做虚拟存储(Virtual Store) 机制。它在项目内模拟传统 node_modules 的嵌套结构,同时在 .pnpm 目录下以包名 + 版本号 的形式为每个版本创建独立文件夹,通过硬链接从全局仓库精准关联对应版本的真实文件;再通过根目录 node_modules 的符号链接,构建出严格的依赖隔离层级。最终实现不同版本的依赖独立存放、精准引用、互不干扰,从根源上杜绝版本冲突,保障复杂依赖关系下项目的稳定运行。

总结:三层架构

层级 位置 内容性质 作用
L1: 全局仓库 ~/.pnpm-store 真实文件 节省磁盘空间,所有项目共享。
L2: 项目仓库 node_modules/.pnpm 硬链接 管理项目内复杂的依赖版本和嵌套关系。
L3: 暴露接口 node_modules/ 符号链接 方便构建工具寻找依赖。

PNPM 安装

必须先安装 Node.js (npm 自带),先去官网装:nodejs.org/(选 LTS 版本)

bash 复制代码
# 安装 pnpm
npm install -g pnpm
​
# 检查是否安装成功
pnpm -v
​
# 初始化 pnpm
pnpm setup
​
# 尝试升级
pnpm self-update

# 国内换源
pnpm config set registry https://registry.npmmirror.com/

PNPM 快速上手

以下是列出常用的命令,具体可以参考官网管理依赖

安装依赖包

csharp 复制代码
pnpm add <pkg>
命令 说明
pnpm add sax 安装并保存到 dependencies(生产依赖)
pnpm add -D sax 安装并保存到 devDependencies(开发依赖)
pnpm add -O sax 安装并保存到 optionalDependencies(可选依赖)
pnpm add -g sax 全局安装
pnpm add sax@next 安装 next 标签对应的版本
pnpm add sax@3.0.0 安装指定版本 3.0.0

安装项目全部依赖

bash 复制代码
pnpm install
# 或简写 pnpm i

更新依赖

bash 复制代码
pnpm update
# 或简写 pnpm up
命令 说明
pnpm up package.json 约定的版本范围内,更新所有依赖
pnpm up --latest 忽略版本范围约束,更新所有依赖到最新版
pnpm up foo@2 foo 更新到 v2 系列的最新版本
pnpm up "@babel/*" 更新 @babel scope 下的所有依赖

删除依赖

csharp 复制代码
pnpm remove # 或简写 pnpm rm
pnpm uninstall # 或简写 pnpm un
# remove 和 uninstall 作用上完全等价

运行脚本

  • 执行 package.json 中定义的脚本:

    xml 复制代码
    pnpm run <script>
  • 运行测试脚本:

    bash 复制代码
    pnpm test
  • 运行启动脚本:

    sql 复制代码
    pnpm start
    # 或
    pnpm run start

初始化 / 创建项目

create-*@foo/create-* 模板快速创建项目:

css 复制代码
pnpm create <starter> [项目名]

示例:

lua 复制代码
pnpm create react-app my-app

常用进阶小技巧

  1. 清理无用依赖

    复制代码
    pnpm prune
  2. 查看依赖来源(排查冲突用)

    matlab 复制代码
    pnpm why react
  3. 删除 node_modules(比手动删更快)

    复制代码
    pnpm store prune
相关推荐
用户8113581881202 小时前
React全家桶笔记(二):React组件核心 — State、Props、Refs
前端
大萝卜呼呼2 小时前
Next.js第二课 - 项目结构详解 - 优栈
前端·next.js
skywalkzf2 小时前
全志 V853 开发:lunch 不显示项目列表问题排查与解决
前端·chrome
踩着两条虫2 小时前
VTJ.PRO 在线应用开发平台的项目模板(Web、H5、UniApp)
前端·低代码·ai编程
云原生指北2 小时前
测试文章标题 - Omnipub 自动发布测试
前端
无责任此方_修行中2 小时前
"JavaScript"这个名字,到底属于谁?一场价值74亿美元的法律战争
前端·javascript·程序员
CharlesY2 小时前
网页排版与编码的隐形神器:HTML字符实体从入门到精通
前端
laamfun2 小时前
VanityH – 面向前端渲染函数的优雅 Hyperscript DSL
javascript
我命由我123452 小时前
React - useEffect、useRef、Fragment
开发语言·前端·javascript·react.js·前端框架·ecmascript·js