昨晚,我体会了没有 pnpm 的痛(二)

简介: 昨晚,我体会了没有 pnpm 的痛(二)

pnpm 是怎么做到的


这就要涉及文件系统中两个概念:硬链接、软链接;


硬链接


在Linux的文件系统中,保存在磁盘分区中的文件不管是什么类型都给它分配一个编号,称为索引节点号(Inode Index),在 Linux 中,允许多个文件名指向同一索引节点,一般这种连接就是硬链接。

硬链接的作用是允许一个文件拥有多个有效路径名,这样用户就可以建立硬链接到重要文件,以防止“误删”的功能。其原因如上所述,因为对应该目录的索引节点有一个以上的链接。只删除一个链接并不影响索引节点本身和其它的链接,只有当最后一个链接被删除后,文件的数据块及目录的链接才会被释放。也就是说,文件真正删除的条件是与之相关的所有硬链接文件均被删除。

语法:ln filename [linkname ]

  1. 硬链接的新建是为同一inode号添加文件名 (本质是在目录条目里为inode号增添一个文件名映射,指向同一个inode表数据,因此数据相同)
  2. 新建硬链接,链接数增加(链接数实质就是 inode号 对应文件名的个数;当 inode 号映射的文件名不存在时,此 inode号就会被系统回收重用)
  3. 硬链接文件和原文件之间数据共享,但又互相独立;(修改其中任意一个文件的数据,其他的文件数据都会改变,删除硬链接文件则对应的链接数会减少,如果是最后一个链接数则直接删除文件。)
  4. 不能跨分区和跨设备创建硬链接
  5. 不能对目录创建硬链接 (目录最多有三个硬链接,目录本身,目录下的 . ,子目录下的 …)

示例: 以下命令建议在 Linux 虚拟机中或 MacOS 中操作:


1. 新建 poetryFile 文件
$ touch poetryFile
2. 给文件输入内容'人生得意须尽欢'
$ echo '人生得意须尽欢'>poetryFile
$ cat poetryFile // 查看内容
3. 通过ln 在同文件路径下建立硬链接文件 hardPoetryFile
$ ln poetryFile hardPoetryFile
4. 修改被硬链接的文件,加上'莫使金樽空对月'
$ echo '莫使金樽空对月'>>hardPoetryFile
$ cat poetryFile


软链接


有点像是 window 中的快捷方式,它本身也是一个文件,只不过保存的是它指向的文件的全路径,访问时将通过它访问所指向的文件路径以打开指定文件,所以当删除源文件时,打开它将报错指示无相关路径。

语法:ln -s filename [linkname ]

  1. 软链接实质是新建一个文件快捷方式,存放的数据是原文件的文件名,文件数据大小是原文件名字的字节数;访问时通过文件名指向到原文件数据
  2. 软链接支持跨分区
  3. 可以创建目录软链接
  4. 软链接文件依赖于原始文件 ;删除原始文件,软链接文件会失效示例: 在 poetryFile 的基础上我们新建一个软链接


$ ln -s poetryFile softPoetryFile // 新建软链接文件
$ cat softPoetryFile // 查看文件内容
人生得意须尽欢,莫使金樽空对月
$ echo '天生我材必有用'>>softPoertFile // 修改软链接内容
$ cat softPoertFile // softPoertFile内容变化
人生得意须尽欢,莫使金樽空对月; 天生我材必有用


在文件当前所在目录通过 ls -hl 查看信息,可以发现硬链接文件和源文件各种信息均一致,可以说是一样的文件,而软链接文件则只是存储了指向信息,所以可以看到明显的差别。


total 16
-rw-r--r--@ 2 zhoumingjie  staff    66B  2  9 10:24 hardPoetryFile
-rw-r--r--@ 2 zhoumingjie  staff    66B  2  9 10:24 poetryFile
lrwxr-xr-x  1 zhoumingjie  staff    10B  2  9 10:21 softPoetryFile -> poetryFile


pnpm对硬链接,软链接的运用


当使用 npm 或 Yarn 时,如果你有100个项目使用了某个依赖(dependency),就会有100份该依赖的副本保存在硬盘上。而在使用 pnpm 时,依赖会被存储在内容可寻址的存储中,所以: 如果你用到了某依赖项的不同版本,那么只会将有差异的文件添加到仓库。 例如,如果某个包有100个文件,而它的新版本只改变了其中1个文件。那么 pnpm update 时只会向存储中心额外添加1个新文件,而不会因为仅仅一个文件的改变复制整新版本包的内容。 所有文件都会存储在硬盘上的某一位置。 当软件包被被安装时,包里的文件会 硬链接 到这一位置,而不会占用额外的磁盘空间。 这允许你跨项目地共享同一版本的依赖。因此,您在磁盘上节省了大量空间,这与项目和依赖项的数量成正比,并且安装速度要快得多! 摘自: pnpm.io/zh/motivati…官方介绍示意图:


1687778160068.png


在pnpm 出现之前,npm 和 yarn 为了提升装包效率以及复用率,采用了扁平化对策略,也就是所有的依赖包都装到根目录下,这样会导致node_modules 下的包和 package.json 中定义的存在很大出入,这会引起幽灵依赖( 幽灵依赖” 指的是项目中使用了一些没有被定义在其package.json 文件中的包。)


如图:


1687778168265.png


虽然我只需要express 这一个包,但是experss 所依赖的包都被平铺到了根目录,这将导致我可以直接使用这些没在 package.json 中定义的包,虽然项目可以运行,但是将是个潜在的隐患。而如果使用 pnpm, 它将使用软链接来解决这个问题:


1687778175185.png


可以看到,node_modules 下结构和我们期望的几乎一样了,很简洁,之前的那些包被放到了 .pnpm 里,其实这里的 express 就是个软链接,执行 ls -hl 查看其详细信息, 可以看到它指向了 .pnpm 下的express 文件,所以说 pnpm 的软链接就是将 node_modules 里的文件软链接到对应的 .pnpm/[package_name]@version/node_modules/[package_name] 中。


total 0
lrwxr-xr-x  1 zhoumingjie  staff    41B  2  9 13:29 express -> .pnpm/express@4.17.2/node_modules/express
lrwxr-xr-x  1 zhoumingjie  staff    47B  2  9 13:29 mime-types -> .pnpm/mime-types@2.1.34/node_modules/mime-types


而 .pnpm 中的文件则是一个对源文件的硬链接,我来验证下,首先找到 pnpm-test 项目下找到 express 的文件路径,通过终端指令 stat -s index.js读取其详细信息,发现其 index.js inode节点为 st_ino=5206568 并且有8个相同的硬链接,然后建一个新项目,并安装express,发现 其节点inode 仍然是st_ino=5206568,但是硬链接数量增加到了 9 个,可以看出express 下的index.js 实际上是被复用的。


1687778185359.png


那么,pnpm 下载的源文件到底在哪里呢,以 macOS 为例,会默认安装到当前用户的根目录下,是一个隐藏文件,你也可以通过修改配置来更换其位置 pnpm config set store-dir /path/to/.pnpm-store


1687778193323.png


总结


pnpm == p(performant) + npm,代表高性能的 npm,我觉得目前可用性已经很好了,虽然可能迁移中会遇到一些问题比如幽灵依赖,但是还是值得升级的。特别是新项目,无脑用起来吧。

目录
相关文章
|
SQL 缓存 Java
终于来新同事了,没想到竟是我噩梦的开始
终于来新同事了,没想到竟是我噩梦的开始
67 0
|
存储 缓存 固态存储
昨晚,我体会了没有 pnpm 的痛(一)
昨晚,我体会了没有 pnpm 的痛(一)
129 0
|
消息中间件 存储 JavaScript
如何写出一手让同事膜拜的漂亮代码?
如何写出一手让同事膜拜的漂亮代码?
|
机器学习/深度学习 人工智能 自然语言处理
【paddlehubOCR项目】网课手酸酸,眼花花,救星来啦!
大家好这里是三岁,今天给大家带来的是在AiStudio项目平台的一个精选项目,虽然很短,但是效果拔群,使用到了最近特别火的paddleOCR~~~
280 0
【paddlehubOCR项目】网课手酸酸,眼花花,救星来啦!
|
JavaScript 前端开发 程序员
巧用NodeJs帮老板解决个人需求!老板娘直呼:"牛!niu!🐂!"
大家好,我是HoMeTown 继上次用Js+Css给Boss秀完肌肉💪🏻,打出组合拳之后,(#敢在我工位装摄像头?吃我一套JS ➕ CSS组合拳!!👊🏻),今天是老板奖励我连续工作的第7/31天,不过就在今天,这个糟糕的事情终于赢来了新的转机,老板有了一个大不大,小不小的个人需求想让我看能不能写一段脚本,帮他度过难关,听完之后,我觉得是时候拿回作为程序员的尊严!展示一把真正的肌肉💪🏻了(破音~~~!)。
171 0
|
中间件 测试技术 开发工具
痛!痛!痛!我们的好兄弟Git,一路走好!
文章是正经文章,标题不要在意,哈哈
痛!痛!痛!我们的好兄弟Git,一路走好!
|
容器
L2-020. 功夫传人
L2-020. 功夫传人
200 0
7-12 功夫传人
7-12 功夫传人 一门武功能否传承久远并被发扬光大,是要看缘分的。一般来说,师傅传授给徒弟的武功总要打个折扣,于是越往后传,弟子们的功夫就越弱…… 直到某一支的某一代突然出现一个天分特别高的弟子(或者是吃到了灵丹、挖到了特别的秘笈),会将功夫的威力一下子放大N倍 —— 我们称这种弟子为“得道者”。
120 0
|
弹性计算 Ubuntu
感想
完成这件事颇为困难 成就一番事业需要外物 任其发展并非长远之计 务实一点 而且在今后肯定更加辉煌 以青年的毅力