npm、yarn及pnpm


npm

npm V3之前存在诸多问题:

  • node_modules文件夹体积过大,比如当多个项目同时引用lodash,就会在node_modules多次安装lodash,很快就会把计算机的磁盘占满,不得不经常通过 rm -rf node_modules 来删除node_modules。
  • 嵌套层级过深,只有当找到不依赖任何包的叶子节点,才会停止,会导致路径过长,在windows会出现删除node_modules失败问题。
  • 安装速度很慢,有目录嵌套的原因,也有安装逻辑的问题,按照队列下载,这就会导致同一个时刻,只有一个模块在下载、解析、安装

npm V3:
提出了扁平化的策略,把嵌套过深的层级,通过扁平化的方式,将依赖包进行提升,使嵌套层级尽可能的变少。
存在的问题:

  • 没有彻底解决重复安装的问题。
  • 存在幽灵依赖问题,比如在安装时把c@1.0.0提升到了顶层,但是在package.json中并没有声明,项目中照样可以引用c@1.0.0
  • 不支持离线缓存模式,安装速度慢。

yarn

针对npm的痛点进行了优化

  • 缓存机制:
    • yarn使用一个全局的缓存目录来存储所有依赖项,而npm使用分散的缓存目录结构。这样使得yarn更加易于管理和维护。
    • yarn拥有离线模式,当你在命令行敲下yarn install 时,会首先尝试使用本地缓存,当你之前已经缓存过这些依赖项,那么在离线模式下也能安装。
  • 并行安装:yarn在设计之初就考虑到了并行安装依赖,默认使用多线程来下载和安装依赖包,使得安装速度更快。
  • 版本锁定更加稳定:如上分析,yarn.lock的文件更加扁平化和准确,能够最大限度避免多个版本依赖问题。

pnpm

  • 节省磁盘空间:所有的依赖包文件都存储在全局的store目录下,当某个项目在安装依赖时,会通过硬链接的方式将依赖资源链接到项目中,而不会再次重复安装依赖包,不占用额外的磁盘空间。
  • 提高安装速度:别的项目安装过的依赖,无需下载,通过硬链接来使用;未安装的依赖,通过并行下载来安装多个依赖
  • 非扁平的node_modules目录: 所有包都与自己的依赖项分组在一起,使用符号链接嵌套依赖

npm、yarn、pnpm特点总结

特点 npm pnpm Yarn
功能 Node.js的默认包管理器,完善的包管理功能,支持包版本管理等 支持共享依赖,减少磁盘空间占用 支持并行安装、离线安装等特性
性能 安装较慢,磁盘空间占用大 安装速度快,磁盘空间占用小 安装速度快,支持并行安装
易用性 简单易用,命令直观 与npm类似,但需注意共享依赖 学习曲线较陡,配置较复杂
安全性 依赖冗余可能存在一定安全隐患 共享依赖可以减少安全隐患 生成yarn.lock文件确保依赖版本一致性

扩展内容

硬链接和符号链接

硬链接

硬链接指的就是,在某个目录下新增一条文件名链接到某个 inode 号码的关联记录,简单来说,就是对一个文件取了别名。
使用硬链接设置链接文件时,磁盘的空间与 inode 的数量都不会改变,不管使用哪个文件名均可以从同一个数据块中读取出相同的数据。而这正是硬链接的好处所在,即安全共享
就是说,我们将任何一个文件删除,其实 inode 和区块都还是存在的,只是将文件的链接数减一而已,此时仍然可以通过另一个文件名来读取到正确的数据。而只有当链接数减到0时,该文件才会从文件系统中彻底删除。此外,不论我们使用哪一个文件名来编辑,最终的结果都会写入到相同的 inode 与区块中,因此均能进行数据的修改。

硬链接的一些限制:

  • 不能跨文件系统
    因为一个文件的 inode 号码是相对于整个文件系统来说的,它是这个文件在当前系统分区中的索引值。若是跨越了文件系统,那么这些链接的 inode 就不是同一个,更不用说数据区块了,所以硬链接是不可能跨越文件系统的。
  • 不能链接目录
    因为如果使用硬链接到目录时,链接的数据需要连同被链接目录下面的所有数据都建立链接。当在某一个目录下创建新文件时,其余链接目录下的数据就要重新建立一次硬链接,这样会造成相当大的环境复杂度。所以,目前硬链接对于目录暂时还是不支持的。
符号链接(软链接)

其实质上就是建立一个独立的文件,而这个文件中存储的是指向它链接的那个文件的文件名。由符号链接所建立的文件会占用新的 inode 与区块,这一点和硬链接是完全不同的。简单来说,可以将符号链接理解为我们常见的快捷方式。
比如为test.txt文件创建一个符号链接文件symbolic.txt,在访问symbolic.txt文件内容的时候,读取到的是test.txt文件名,然后再读取test.txt对应的区块内容。

硬链接适用于共享相同数据的文件,而符号链接适用于创建快捷方式或引用目标文件的情况。

| | 硬链接 | 符号链接 |
|创建 | 只能在同一文件系统中创建 | 可以跨越文件系统创建 |
|目标 | 只能指向普通文件 | 可以指向文件或目录 |
|磁盘空间 | 共享相同的磁盘空间 | 需要额外的磁盘空间 |
|链接计数 | 链接计数相同 链接计数不同 |
|更改影响 | 修改一个链接会影响其他链接和原始文件 | 修改链接不会影响其他链接和原始文件 |
|删除原始文件 | 不影响其他链接和原始文件 | 链接成为”断链”,无法访问目标文件 |

参考资料

探究前端包管理工具:npm、yarn 和pnpm
辨析:硬链接与符号链接
九、Linux链接文件管理——硬链接、符号链接


文章作者: Snail-Lu
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Snail-Lu !
  目录