2023-12-13 浅谈pnpm

什么是幻影依赖

我们知道npm、yarn安装依赖包的时候是平铺的结构,如下图:

疑问:明明我package.json文件里只声明了express一个包,为啥有这么多的包被安装到node_modules目录中?

原因其实也都知道,是express这个包又依赖了其他的包,所以就一起安装进来了

那幻影依赖顾名思义就是没有在package.json文件里声明的依赖又出现在了node_modules目录中,这些依赖在生产版本中可能会造成影响

比如在文件中使用了lodash这个库,但是没有在package.json里声明这个依赖,这个依赖就是上述说的幻影依赖

一般会造成两个问题

一个是版本问题:

项目中声明了A库版本v1,A依赖于B库版本v1,这时候项目直接使用了B库(B库没有声明是幻影依赖);下一次升级A库到v2时候,依赖的B库也可能会升级到v2,这时候项目中使用的还是B库v1的版本,造成代码莫名其妙的报错,这种问题还不好排查,等到发生的时候再排查问题就大了

除了版本问题外,另外的一个问题是依赖丢失的问题:

如果A库是开发依赖,则导致在开发环境使用幻影依赖B库没有问题,但是一旦部署的时候就会导致生产环境没有安装开发依赖,使得B依赖丢失,则项目中使用的这个库找不到了,就会在生产环境上报错,那问题大了

解决方法

发现幻影依赖的本质原因后,解决方法也很简单

一种方法就是直接安装这个幻影依赖,这种做法直接有效,但是有个缺陷,就是有时候项目太大了,安装的依赖包太多了,开发人员不会一一去排查包是否是幻影依赖,会直接使用vscode中的智能提示,但是这种智能提示是根据在node_modules中是否有这个库去显示的,这时候就需要一种工具,提示在package.json中没有声明的依赖,你在代码中使用就要报错,马上提示这个库要安装

经常说的依赖关系树其实是一个依赖图结构,如上左侧所示

而把依赖安装过后,到文件系统中又变成文件树结构如上图中间所示,这种方式最早的时候就是npm用的文件方式这样会有重复文件

后来npm升级后以及yarn出现后就会把依赖安装成上图右边所示,扁平结构,这里就造成了幻影依赖了

使用pnpm

pnpm工具的出现完美的解决了上述问题,使用pnpm安装包后,会出现上图中间和右边所示的关系

首先会有个仓库形式的store,这里存储的是所有的安装包以及其依赖包,中间图所示的还是各个依赖之间的关系,不过是以符号链接-即软连接的方式存储的,实际指向的是store中的文件地址

使用pnpm安装的包,在package.json里未声明的包在node_modules下是找不到的,这样在项目中引入就不会有提示,还会报错,上图右边的小箭头指的就是符号链接也就是软连接,真正的包地址是在./node_modules/.pnpm/express@4.18.2/node_modules/express,express的依赖包又被软连接到.pnpm/node_modules目录下

硬连接:是指向文件或者目录的实际物理位置的直接引用,硬连接创建一个新的文件入口,但不创建新的文件内容,它与原始文件共享相同的inode(文件的唯一标识符)和数据块,因此,对硬连接的任何操作都会直接影响原始文件,删除原始文件或硬连接中的任何一个都不会导致数据丢失,只要至少还有一个硬连接存在

软连接(符号链接):是一种特殊类型的文件,包含了对另外一个文件或目录的引用,类似于快捷方式,软连接不直接指向文件的物理位置,而是通过文件路径名来引用目标文件或目录,当访问软连接时,操作系统会自动将其解析为目标文件或目录,删除软连接不会影响原始文件或目录的存在,但如果目标文件或目录被删除,软连接将变为无效

在pnpm中,默认情况下,使用软连接(符号链接)将项目的直接依赖添加到根目录下的node_modules文件夹下,而.pnpm目录中保存的直接和间接依赖的硬连接

下图是pnpm、npm、yarn的对比

相关推荐
辻戋2 小时前
从零实现React Scheduler调度器
前端·react.js·前端框架
徐同保2 小时前
使用yarn@4.6.0装包,项目是react+vite搭建的,项目无法启动,报错:
前端·react.js·前端框架
Qrun3 小时前
Windows11安装nvm管理node多版本
前端·vscode·react.js·ajax·npm·html5
中国lanwp3 小时前
全局 npm config 与多环境配置
前端·npm·node.js
JELEE.4 小时前
Django登录注册完整代码(图片、邮箱验证、加密)
前端·javascript·后端·python·django·bootstrap·jquery
TeleostNaCl6 小时前
解决 Chrome 无法访问网页但无痕模式下可以访问该网页 的问题
前端·网络·chrome·windows·经验分享
前端大卫7 小时前
为什么 React 中的 key 不能用索引?
前端
你的人类朋友7 小时前
【Node】手动归还主线程控制权:解决 Node.js 阻塞的一个思路
前端·后端·node.js
小李小李不讲道理9 小时前
「Ant Design 组件库探索」五:Tabs组件
前端·react.js·ant design
毕设十刻9 小时前
基于Vue的学分预警系统98k51(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js