从npm到yarn,再到pnpm

一、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的通病。

硬链接:通过索引节点来进行链接。可以理解为:为一个文件数据创建了多个副本,每个副本都通过索引节点指向了源文件数据

  • 硬链接是指向目标数据对象的链接
  • 必须从一个原始文件创建
  • 硬链接是不占用实际空间的,只是指向了文件数据。
  • 不能对目录操作
  • 删除任意一个硬链接和源文件,其他的硬链接仍然可以使用,必须删除所有的硬链接和原始文件数据才真的删除

软链接:也称为符号链接,是包含了源文件位置信息的特殊文件,本身是一个单独的文件。可以理解为:指向源文件的相对路径/绝对路径

  • 符号链接是指向目标路径的链接
  • 可对不存在的目录和文件创建软链接
  • 明确自己是符号链接文件,并存放了指向源文件位置的信息
  • 可以对目录和文件操作
  • 删除软链接并不影响被指向的文件,但源文件被删除则相关的软链接将会失效(死链接)
相关推荐
前端小小王15 分钟前
React Hooks
前端·javascript·react.js
迷途小码农零零发24 分钟前
react中使用ResizeObserver来观察元素的size变化
前端·javascript·react.js
娃哈哈哈哈呀1 小时前
vue中的css深度选择器v-deep 配合!important
前端·css·vue.js
旭东怪1 小时前
EasyPoi 使用$fe:模板语法生成Word动态行
java·前端·word
ekskef_sef3 小时前
32岁前端干了8年,是继续做前端开发,还是转其它工作
前端
sunshine6413 小时前
【CSS】实现tag选中对钩样式
前端·css·css3
真滴book理喻4 小时前
Vue(四)
前端·javascript·vue.js
蜜獾云4 小时前
npm淘宝镜像
前端·npm·node.js
dz88i84 小时前
修改npm镜像源
前端·npm·node.js
Jiaberrr4 小时前
解锁 GitBook 的奥秘:从入门到精通之旅
前端·gitbook