pnpm、yarn、npm

本质区别

特性 npm yarn pnpm
存储结构 每项目独立存依赖,层层嵌套,目录大。 扁平结构,多个版本仍需嵌套,存储略优化。 使用全局 .pnpm-store,项目通过硬链接引用,节省空间。
安装机制 串行下载并写入 node_modules,速度慢。 并行安装,加快依赖写入速度。 并行 + 去重 + 硬链接,减少重复写入和磁盘 I/O。
缓存方式 包存于 .npm/_cache,安装仍需解压复制。 下载压缩包到 .yarn/cache,仍需解压。 内容寻址缓存,直接链接使用,无解压、无复制。
锁文件 package-lock.json,结构详尽但大,合并冲突复杂。 yarn.lock,结构简洁,版本控制友好。 pnpm-lock.yaml,基于内容哈希,唯一性强,冲突少。
node_modules 扁平 + 自动依赖提升,容易产生“幽灵依赖”问题。 同样扁平,但支持配置禁用某些提升。 每依赖独立路径管理,更接近真实包关系,可选 hoist,默认更安全。
工作区支持 v7 起支持 workspaces,功能基础,缺少工具链集成。 原生支持,可统一依赖、构建、执行脚本,适合 monorepo。 原生支持 + -r/-F 命令支持递归构建、过滤执行,最强 monorepo 支持。

npm、yarn的两问题

  1. 幽灵依赖,项目当前引用的a包可能是作为b包的依赖而下载的,哪一天b包不依赖a包了,项目就会运行失败

  2. 并非完全平铺,同一包存在多版本时依旧嵌套

幽灵依赖: 有些包没有在package内显示引用,而是作为依赖包的依赖被下载,平铺在modules内 因而这些(package内)看不见的依赖包可以被开发者正常引用 pnpm有了更严格的要求,必须显示引用

pnpm的两部步解法

  1. 回归使用多层嵌套依赖,以解决幽灵依赖问题

  2. 项目中依赖包全部使用软硬连接,包只在盘符根目录.pnpm-store存一份,以解决重复下载包的问题

node_modules内的包,与package内的引用一一对应,且多出一个.pnpm .pnpm 内平铺了所有 package包的依赖 及其 多层嵌套依赖,同npm、yarn .pnpm 平铺的包全部 硬链接 自全局store .pnpm 平铺的包相互 软连接 实现相互依赖,借此以平铺做到多层嵌套相同效果

优点: 安装快,删除快,节省磁盘,多项目共享缓存,

pnpm其他优势

  1. pnpm是并发调度下载

  2. pnpm原生支持 monorepo

  3. pnpm-lock.yaml 结构更清晰

workspaces 机制专为 monorepo 设计,处理包依赖拓扑结构更加高效

pnpm使用碰见的问题

待更新

参考链接

神光大佬的pnpm 是凭什么对 npm 和 yarn 降维打击的