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
对应的区块内容。
硬链接适用于共享相同数据的文件,而符号链接适用于创建快捷方式或引用目标文件的情况。
| | 硬链接 | 符号链接 |
|创建 | 只能在同一文件系统中创建 | 可以跨越文件系统创建 |
|目标 | 只能指向普通文件 | 可以指向文件或目录 |
|磁盘空间 | 共享相同的磁盘空间 | 需要额外的磁盘空间 |
|链接计数 | 链接计数相同 链接计数不同 |
|更改影响 | 修改一个链接会影响其他链接和原始文件 | 修改链接不会影响其他链接和原始文件 |
|删除原始文件 | 不影响其他链接和原始文件 | 链接成为”断链”,无法访问目标文件 |