一、npm 和 yarn:
1、npm早期版本的问题,yarn的出现
1-1、npm早期版本
npm是node默认的包管理器,跟随node安装,但是早期的npm版本主要存在问题:
-
依赖嵌套,当嵌套层级比较深时,部分操作系统和程序无法处理过长的文件路径;依赖嵌套导致重复安装相同的包。
-
依赖结构的不确定:早期的npm并没有版本锁定的东西,无法保证不同的人下载相同版本的依赖,容易出现"在我电脑上"的问题。依赖版本不一致,主要是因为npm的语义版本控制(semver)引起的:
md给定一个版本号:主版本号.次版本号.补丁版本号, 以下这三种情况需要增加相应的版本号: 主版本号: 当API发生改变,并与之前的版本不兼容的时候 次版本号: 当增加了功能,但是向后兼容的时候 补丁版本号: 当做了向后兼容的缺陷修复的时候 在package.json中包的版本号有以下几种: 固定主版本:^1.0.1,会安装1.x.x中的最新版本(不低于1.0.1) 固定次版本:~1.0.1,会安装1.0.x中的最新版本(不低于1.0.1) 固定版本号:1.0.1,只会安装1.0.1版本
-
下载慢:npm是串行顺序下载
1-2、yarn的出现
2016年10月Facebook为了解决npm的这些问题,发布了yarn,yarn一开始主要为了解决npm的问题:
- 依赖嵌套:采用了扁平依赖关系树来解决这个问题
- 依赖结构的不确定:使用yarn.lock文件以确保使用的库的版本相同
- 下载慢:使用并行下载
1-3、npm的后期版本
npm在新的包管理器推动下,后续版本也解决了低版本存在的问题:
- 依赖嵌套:采用了扁平依赖关系树来解决这个问题
- 依赖结构的不确定:使用package-lock文件以确保使用的库的版本相同
- 下载慢:支持缓存
所以,很多东西还是需要新鲜血液来刺激才会有进步,不然就是摆烂,反正就这样你爱用不用。。。。。
2、npm 和 yarn安装依赖过程
- 1、解析确定版本号
- 2、下载依赖压缩包
- 3、将压缩包解压到缓存
- 4、将缓存中的依赖copy到项目node_modules
3、npm 和 yarn共同点
- 扁平依赖树
- 安装依赖操作大致相同
- 都使用lock文件进行依赖版本控制
4、npm 和 yarn两者的差异
- 命令行存在区别
- yarn安装依赖时并行安装,而npm使用串行安装
- yarn支持离线从缓存安装依赖,npm虽然也有缓存但不支持离线安装
- yarn在npm的基础上还做了其他的改进
- yarn最初是为了解决npm的问题而出现的,而npm也因为yarn的出现改善了很多
5、yarn/npm的通病
- 扁平依赖关系树:扁平化算法本身的复杂性很高,耗时较长
- 幽灵依赖:也就是在项目安装了A模块,A模块依赖了B模块,因为扁平依赖树会将B模块提升到node_module 下面,但是在项目的package.json中是没有的B模块的,这个时候再项目中调用这个B模块时是可以调用到的,这就叫幽灵依赖。幽灵依赖主要会产生以下问题:比如某天模块A不再依赖B模块,而项目还在调用了B模块,这个时候程序就会报错找不到B。
- 重复的依赖安装:虽然yarn和npm都提供了缓存,但是每个项目安装相同的包,都要在项目下面的node_modules中安装,相同的内容在各项目中重复的安装,大量占用了磁盘空间
1-5、pnpm的出现
二、pnpm
pnpm 的作者Zoltan Kochan发现 yarn/npm 并没有打算去解决上述的这些问题,于是另起炉灶,写了全新的包管理器,开创了一套新的依赖管理机制。
- pnpm主要利用硬链接和符号链接来避免复制所有本地缓存源文件。
- 根目录下的 node_modules 下面不再是眼花缭乱的依赖,而是跟 package.json 声明的依赖基本保持一致。避免了幽灵依赖。
- 包和依赖提升到同一级别,通过软连接实现了依赖的"嵌套"结构,避免了扁平化算法慢和嵌套依赖的问题
总的来说,yarn是为了解决npm的问题而出现的,实在npm的基础上做了优化,尽管npm也解决了一些以前的问题,但yarn的并行安装还是比npm的串行安装更快,但二者的依赖管理机制大致相同,存在相同的问题;pnpm则是开创了一套新的依赖管理机制,解决了yarn和npm的通病。
硬链接:通过索引节点来进行链接。可以理解为:为一个文件数据创建了多个副本,每个副本都通过索引节点指向了源文件数据
- 硬链接是指向目标数据对象的链接
- 必须从一个原始文件创建
- 硬链接是不占用实际空间的,只是指向了文件数据。
- 不能对目录操作
- 删除任意一个硬链接和源文件,其他的硬链接仍然可以使用,必须删除所有的硬链接和原始文件数据才真的删除
软链接:也称为符号链接,是包含了源文件位置信息的特殊文件,本身是一个单独的文件。可以理解为:指向源文件的相对路径/绝对路径
- 符号链接是指向目标路径的链接
- 可对不存在的目录和文件创建软链接
- 明确自己是符号链接文件,并存放了指向源文件位置的信息
- 可以对目录和文件操作
- 删除软链接并不影响被指向的文件,但源文件被删除则相关的软链接将会失效(死链接)