当前位置: 首页 > news >正文

5.4 4pnpm 使用介绍

  • pnpm 官网:https://pnpm.io/   高性能的 Node.js 包管理工具

一、什么是 pnpm?

pnpmPerformant npm)是一个高性能、节省磁盘空间的 Node.js 包管理工具,兼容 npm 生态。它由 Zoltan Kochan 于 2016 年创建,目标是解决 npm 和早期 yarn 在依赖管理中的性能与磁盘占用问题。

pnpm 的核心优势在于其独特的 硬链接 + 内容可寻址存储(Content-Addressable Storage, CAS) 机制,使其在安装速度、磁盘使用和依赖一致性方面表现卓越。


二、pnpm 的核心原理

1. 硬链接(Hard Links)与符号链接(Symlinks)

与 npm/yarn 直接复制依赖包不同,pnpm 使用 硬链接 来引用全局存储中的包,避免重复下载和存储。

  • 全局内容存储(Content Store)
    pnpm 将所有包存储在一个全局目录中(如 ~/.pnpm-store),每个包只保存一份。
  • 项目中使用硬链接
    项目 node_modules 中的依赖通过 硬链接 指向全局存储中的文件,不占用额外磁盘空间。
  • 扁平化结构 + 符号链接
    pnpm 使用 符号链接 构建依赖树,确保依赖可解析,同时避免“幻影依赖”(phantom dependencies)。

2. 内容可寻址存储(CAS)

包文件根据其内容生成唯一哈希值作为存储路径,确保:

  • 相同内容只存储一次
  • 文件完整性高(内容变化则哈希变化)
  • 支持离线安装(若包已存在于 store)

3. 严格的依赖结构(Strict Node Modules)

pnpm 构建的 node_modules扁平且严格的,只包含项目直接依赖和其子依赖的符号链接,不会提升无关包,从而:

  • 防止“幻影依赖”(即项目使用了未声明的依赖)
  • 提高依赖一致性
  • 减少 node_modules 体积

✅ 例如:A 依赖 B,B 依赖 C。pnpm 中 C 只在 B 的 node_modules 下,A 无法直接 require('C'),除非 A 显式声明依赖 C。


三、pnpm vs npm vs yarn:对比分析

特性pnpmnpmyarn (classic)
安装速度⚡️ 极快(硬链接)慢(复制文件)快(缓存)
磁盘占用💾 极小(全局 store)大(重复复制)较大(缓存+复制)
依赖结构✅ 严格、扁平❌ 提升依赖(幻影依赖)❌ 提升依赖
离线安装✅ 支持(store 存在即可)❌ 无缓存则失败✅ 支持
零安装(PnP)❌ 不支持❌ 不支持✅ yarn 2+ 支持
钩子脚本(hooks)✅ 支持 pnpmfile.js
工作区(Workspace)✅ 强大支持✅ npm 7+
兼容性✅ 完全兼容 npm registry

📌 结论:pnpm 在性能、磁盘效率和依赖安全方面全面领先。


四、快速上手:安装与基本使用

1. 安装 pnpm

# 使用 npm 安装(推荐首次安装)
npm install -g pnpm# 或使用 corepack(Node.js 16.13+ 内置)
corepack enable
corepack prepare pnpm@latest --activate# 验证安装
pnpm --version

2. 常用命令速查

命令说明
pnpm add <pkg>安装包(--save 默认)
pnpm add -D <pkg>安装为开发依赖
pnpm add -g <pkg>全局安装
pnpm remove <pkg>卸载包
pnpm install安装所有依赖
pnpm update更新依赖
pnpm run <script>运行 package.json 中的脚本
pnpm list查看已安装包
pnpm outdated检查过期依赖
pnpm audit安全漏洞扫描
pnpm doctor检查环境问题

3. 初始化项目

pnpm init
pnpm add vue react lodash  # 安装依赖
pnpm add -D typescript eslint  # 安装开发依赖

五、高级特性详解

1. 工作区(Workspaces)

pnpm 支持多包项目(monorepo),通过 pnpm-workspace.yaml 管理。

# pnpm-workspace.yaml
packages:- 'packages/*'- 'apps/*'
// packages/shared/package.json
{"name": "@myorg/shared","version": "1.0.0"
}
// apps/web/package.json
{"dependencies": {"@myorg/shared": "workspace:*"}
}

使用 workspace:* 可本地链接包,无需发布即可开发调试。

2. 共享依赖存储(Shared Store)

所有项目共享同一个全局 store,默认路径:

  • macOS/Linux: ~/.pnpm-store
  • Windows: %LOCALAPPDATA%\pnpm-store

可通过 .npmrc 配置:

store-dir=/path/to/custom/store
  • 路径
    • macOS / Linux~/.npmrc (即 /Users/你的用户名/.npmrc 或 /home/你的用户名/.npmrc
    • WindowsC:\Users\你的用户名\.npmrc

3. pnpmfile.js:自定义行为

创建 pnpmfile.js 可拦截和修改安装行为(如替换包、重写版本)。

// pnpmfile.js
function readPackage(pkg) {// 将 lodash 替换为 lodash-esif (pkg.name === 'lodash') {pkg.name = 'lodash-es'}return pkg
}module.exports = { readPackage }

4. 选择器(Selectors)与过滤器

在工作区中精确操作子包:

# 在所有包中运行构建
pnpm -r build# 在名为 "web" 的包中安装依赖
pnpm add react --filter web# 构建依赖图中 web 包及其依赖
pnpm build --filter web...

5. 离线模式与缓存

# 强制使用缓存(离线安装)
pnpm install --offline# 查看缓存
pnpm store status# 清理无效包
pnpm store prune

六、最佳实践与注意事项

✅ 推荐做法

  1. 新项目优先使用 pnpm
    • 性能高、节省磁盘、依赖安全。
  2. 启用工作区管理 Monorepo
    • 使用 pnpm-workspace.yaml 统一管理多包。
  3. 使用 pnpm-lock.yaml
    • 锁定依赖版本,确保团队一致性。
  4. 定期清理 store
    pnpm store prune  # 删除未使用的包
  5. 结合 pnpm-ctl 或 changesets 管理版本发布

⚠️ 注意事项

  1. 某些工具不兼容硬链接

    • 如 Docker 构建、CI/CD 中需注意文件系统支持。
    • 解决方案:使用 --shamefully-hoist(不推荐)或调整 CI 配置。
  2. 避免 shamefully-hoist

    • pnpm install --shamefully-hoist 会提升依赖,破坏严格性,仅用于兼容旧工具。
  3. IDE 支持

    • WebStorm、VS Code 均良好支持 pnpm。
    • 确保 TypeScript 路径解析正确。
  4. 迁移现有项目

    # 删除 node_modules 和 lock 文件
    rm -rf node_modules package-lock.json yarn.lock
    # 重新安装
    pnpm install

七、常见问题(FAQ)

Q1: pnpm 为什么更快?

  • 硬链接避免文件复制,CAS 缓存避免重复下载。

Q2: 能否与 npm/yarn 混用?

  • 可以,但不推荐。混用会导致多个 node_modules 和锁文件冲突。

Q3: 如何查看全局安装的包?

pnpm list -g --depth=0

Q4: 如何发布包?

与 npm 相同:

pnpm publish

八、总结

pnpm 是当前最高效、最节省资源的 Node.js 包管理工具,特别适合:

  • 大型项目或 Monorepo
  • 团队协作(依赖一致性高)
  • CI/CD 环境(安装快、缓存友好)
  • 本地开发(节省磁盘空间)

选择 pnpm 的理由:

  • ⚡️ 安装速度极快
  • 💾 磁盘占用极小
  • 🔒 依赖结构严格,避免幻影依赖
  • 🧩 工作区支持强大
  • 🔄 完全兼容 npm 生态

建议:无论是新项目还是老项目迁移,pnpm 都是当前最值得推荐的选择

http://www.dtcms.com/a/340302.html

相关文章:

  • 给你的Unity编辑器添加实现类似 Odin 的 条件显示字段 (ShowIf/HideIf) 功能
  • Scikit-learn 预处理函数分类详解
  • pnpm : 无法加载文件 C:\Program Files\nodejs\pnpm.ps1,因为在此系统上禁止运行脚本。
  • 在 React 中,​父子组件之间的通信(传参和传方法)
  • scikit-learn/sklearn学习|变量去中心化和标准化
  • 2.3 Flink的核心概念解析
  • 详解flink java table api基础(三)
  • Flink Stream API - 顶层Operator接口StreamOperator源码超详细讲解
  • OSPF 典型组网
  • CISP-PTE之路--10文
  • 公有地址和私有地址
  • 【GPT入门】第51课 将hf模型转换为GGUF
  • 深入(流批【牛批】框架)Flink的机制
  • 【Java后端】Spring Boot 全局异常处理最佳实践
  • ssl代理
  • 一会儿能ping通一会ping不通解决方案
  • JavaScript手录18-ajax:异步请求与项目上线部署
  • AI 自动化编程 trae 体验 页面添加富编辑器
  • (5)软件包管理器 yum | Vim 编辑器 | Vim 文本批量化操作 | 配置 Vim
  • 深度解析:RESTful API中的404错误 - 不是所有404都是Bug
  • Vue 3项目中的路由管理和状态管理系统
  • 【Day 31】Linux-LNMP
  • MySQL基础操作
  • SpringBoot + MyBatis-Plus 使用 listObjs 报 ClassCastException 的原因与解决办法
  • Rabbit 实战指南-学习笔记
  • HTML+CSS:浮动详解
  • 3D文档控件Aspose.3D实用教程:使用 C# 构建 OBJ 到 U3D 转换器
  • awk 基础用法示例
  • 测试DuckDB插件对不同格式xlsx文件的读写效率
  • MyCAT分库分表