pnpm:优化依赖管理、提升性能的全新包管理利器

技术 · 03-03 · 访问: 912 次

简介

pnpm(performant npm)在 2017 年正式发布,定义为快速的,节省磁盘空间的包管理工具,开创了一套新的依赖管理机制。

优势

在介绍 pnpm 的优势之前,先来了解一下在以前 npm 和 yarn 的一些问题。

早期的 npm1、npm2 主要是采用简单的依赖递归方式,造成了高度的依赖嵌套,此时就造成了以下问题:

  1. 重复依赖嵌套地狱:重复大量的依赖嵌套,增加文件体积,造成了磁盘空间的浪费,使得安装速度过慢。
  2. 文件路径过长:window 系统下,路径过长会导致爆错,最多260多个字符。

之后 npm3 采用扁平化的方式,将依赖提升到根目录,解决了路径过长的问题,但是也带来了新的问题:

  1. 扁平化依赖算法耗时长
  2. 幻影依赖(Phantom dependencies):由于扁平化的方式使得依赖提升到了根目录,此时项目中的 package.json 并没有记录某个依赖,但是却能够在项目中使用,此时就造成了幻影依赖。幻影依赖可能会导致依赖之间的兼容问题,导致项目不能正常运行。
  3. 不确定性(Non-Determinism):由于依赖提升只能提升一个,如 A包安装B@1,C包和D包安装B@2,此时一个B依赖拥有两个版本,此时只提升一个,提升方式是谁先安装就先提升谁,这里可以就会造成生成环境和开发环境中的 node_modules 结构不同问题。
  4. 依赖分身(doppelgangers):A 和 B 依赖 C@1,D 和 E 依赖 C@2,由于依赖提升只能提升一个,所以无论提升 C@1 还是 C@2,都会造成包的重复安装。如下:
node_modules
├── A
├── B
├── C@1
├── D
    └── node_modules
        └── C@2.0
└── E
    └── node_modules
        └── C@2.0

之后 yarn 解决了 npm3 扁平化依赖算法耗时问题,就是通过 lock file,yarn 通过生成一个 yarn.lock 文件,来记录依赖的版本。

剩下的幻影依赖和依赖分身则在 pnpm 中得到了解决。

pnpm 通过内存寻址存储的方式,将依赖存储在系统磁盘上,依赖每个版本只会在系统中安装一次,使用时都会直接硬链接指向该依赖,解决了依赖分身问题,极大节省磁盘空间,并且加快安装速度。

之后在 pnpm 中模块通过软链接指向 node_modules 目录下的真实模块,解决了幽灵依赖问题。

硬链接是多个文件名指向同一个文件的实际内容,而软链接(符号链接)是一个独立的文件,指向另一个文件或目录的路径
  • 硬链接 Hard link:硬链接可以理解为源文件的副本,项目里安装的其实是副本,它使得用户可以通过路径引用查找到全局 store 中的源文件,而且这个副本根本不占任何空间。
  • 符号链接 Symbolic link:也叫软连接,可以理解为快捷方式,pnpm 可以通过它找到对应磁盘目录下的依赖地址。

总结

pnpm 是从全局 store 硬连接到 node_modules/.pnpm,然后之间通过软链接来组织依赖关系。

pnpm 的优势

pnpm 不仅提高了安装速度、节约了磁盘空间、避免了“依赖分身(doppelgangers)”和“幻影依赖(Phantom dependencies)”的问题。而且 yarn 支持的:安全、离线模式、更快的速度,pnpm 都支持,而且速度还要更快。

安装

npm i pnpm -g

常用命令

查看版本

pnpm -v

安装依赖

pnpm install [package-name]

卸载依赖

pnpm uninstall [package-name]

升级 pnpm

pnpm add -g pnpm to  update

设置源

pnpm config get registry # 查看源

pnpm config set registry https://registry.npmmirror.com # 切换淘宝源 

参考

pnpm nodejs包管理工具
icon_mrgreen.gificon_neutral.gificon_twisted.gificon_arrow.gificon_eek.gificon_smile.gificon_confused.gificon_cool.gificon_evil.gificon_biggrin.gificon_idea.gificon_redface.gificon_razz.gificon_rolleyes.gificon_wink.gificon_cry.gificon_surprised.gificon_lol.gificon_mad.gificon_sad.gificon_exclaim.gificon_question.gif
Theme Jasmine by Kent Liao