1、历史原因解读
pnpm这个东西发布的时间是比较早的,但是在最近一两年的时候才开始流行,甚至是可以说非常的盛行,那么这个包到底是个什么东西的,那么我们先说下,原来的包管理工具到底有那些问题?比如说我们以前学习过 npm/yarn/cnpm/npx,这三个在安装我们一个包的时候有两个位置可以安装,一个是局部一个全局,那么我们来思考一下假如我们来安装一个包的时候,比如说我们我们这里有一个项目为project01.现在我们来开发一个项目都是要通过webpack来进行打包的,我们必然需要安装webpack,刚才我们在安装webpack的时候,同时也帮我安装了几十个其他的包,因为webpack本身也依赖其他的包,但是真实开发你不能只用一个webpack,还有一些别的包,babel/less/Vue/VueRouter/Vuex/Pinia/axios.等等一大堆的包...,在我的电脑上我们不可能只开发一个项目,我们会开发很多的很多的项目,项目一、项目二、项目三,一个电脑上是可能存在几个、到几十个、甚至上百个项目的,这里的项目不是指正式的公司项目(当然小公司可能就1-3个),但是你学习阶段,会创建不同的Demo项目,也就是每个项目都需要一份对应的依赖库,如果每个项目都是1个G的模块包。那么我们电脑上,光这堆乱七八遭的依赖就非常的大。电脑不得炸掉npm\yarn都没有解决这个问题,pnpm解决了这个问题。
2、什么是pnpm
什么是pnpm呢?我们来看一下官方的解释:
-
pnpm:我们可以理解成是performant(高性能的) npm缩写;
哪些公司在用呢?
- 包括Vue在内的很多公司或者开源项目的包管理工具都切换到了pnpm;
3、硬连接和软连接的概念
维基百科的解释,当你不会一个技术需要学习时,请先维基百科,了解下最为准确的定义,尽管他们晦涩难懂
硬链接(hard link):
硬链接(英语:hard link)是电脑文件系统中的多个文件平等地共享同一个文件存储单元;
删除一个文件名字后,还可以用其它名字继续访问该文件;
符号链接(软链接soft link、Symbolic link):
符号链接(软链接、Symbolic link)是一类特殊的文件;
其包含有一条以绝对路径或者相对路径的形式指向其它文件或者目录的引用;
快捷方式就是软连接 、文件寻址找到对应的数据是硬链接
4、软链接和硬链接的测试演练
文件的拷贝
文件的拷贝每个人都非常熟悉,会在硬盘中复制出来一份新的文件数据;
sh
window: copy foo.js foo_copy.js
macos : cp foo.js foo_copy.js
文件的硬链接
sh
window: mklink /H aaa_hard.js aaa.js
macos : ln foo.js foo_hard.js
文件的软连接
sh
window: mklink aaa_soft.js aaa.js
macos : ln -s foo.js foo_copy.js
5、pnpm到底做了什么
当使用npm或Yarn时,如果你==有100个项目 ,并且所有项目都有一个相同的依赖包,那么, 你在硬盘上就需要保存100 份该相同依赖包的副本。==
如果是使用pnpm,依赖包将被存放在一个统一的位置,因此:
- 如果你对同一依赖包使用相同的版本,那么磁盘上只有这个依赖包的一份文件;
- 如果你对同一依赖包需要使用不同的版本,则仅有版本之间不同的文件会被存储起来;
- 所有文件都保存在硬盘上的统一的位置:
- 当安装软件包时, 其包含的所有文件都会硬链接到此位置,而不会占用 额外的硬盘空间;
- 这让你可以在项目之间方便地共享相同版本的 依赖包;
为什么效率高,因为应用了硬链接,只是创建硬链接,而不是从新下载,而不用占用额外的磁盘空间
6、pnpm创建非扁平的node_modules目录
pnpm创建的是一个非扁平的node_modules目录,这个也是pnpm的一个特点,但是这个的话也并不是他脱颖而出的一个点,但是确实是这个点还是有一点自己的特色的,并且的话这个特点也算是他的优势之一。
那什么是扁平的node_modules呢?
像我们最近用的npm,或者是yarn,他如果在安装很多包的时候,他就是按照一种扁平化的方式在管理我们的包的,我们观察通过npm安装的包,发现包都是在node_modules这个目录下管理的,如下图
解释
如果我安装webpack这个包,那么webpack所需要的一些依赖包,也是放在node_modules这个目录下的,并不是在webpack目录下还存在一个node_modules,然后把依赖的其他包放进去,早期的npm确实是按照这种方式进行管理,但是会造成同一个包会安装很多次,所以后来的话,不管是yarn,还是npm都将他变成了扁平式的,从而避免重复下载的问题,但是做成扁平化也是有一定的弊端的,比如A包里边有C包,但是我没有安装过C包,C包却能通过代码编写的方式进行使用C包,假如有一天我卸载了A包,C包也许就随之也被卸载掉了,代码跑起来肯定会报错,这是非常别扭、不规范、不安全的。pnpm解决了这个问题
当使用npm或 Yarn Classic安装依赖包时,所有软件包都将被提升到node_modules的 根目录下。
- 其结果是,源码可以访问 本不属于当前项目所设定的依赖包;
7、pnpm的安装和使用
那么我们应该如何安装pnpm呢?
- 官网提供了很多种方式来安装pnpm:https://www.pnpm.cn/installation
- 因为我们每个同学都要求安装过Node,Node中有npm,所以我们通过npm安装即可;
安装pnpm的命令
sh
npm install -g pnpm
检查pnpm的安装版本
sh
pnpm -v
注意:2024-06-29,安装的pnpm的版本为pnpm9,但是他必须要使用node18,没办法我只能卸载掉,因为我公司用的node才16版本。
卸载pnpm
sh
npm uninstall pnpm
pnpm与node的版本对应关系
更多命令和用法可以参考pnpm的官网:https://pnpm.io/zh/
兼容性:https://pnpm.io/zh/installation#兼容性
pnpm与npm等价命令的对照表,帮助你快速入门:
require,引入包查找顺序内容回顾
默认情况下,会去查找是不是node的核心模块,如果不是的话他就会去node_modules里边进行查找。我们观察通过pnpm安装的axios的那些依赖包,是没有在
node_modules包下显示的,所以他是一个非扁平化的node_modules
我们仔细观察axios这个目录我们会在他的右侧发现有一个小箭头,表示为他是一个软链接
切记他并不是直接对远程仓库的npm仓库的包建立了一个软链接,而是在你的每个目录里面都是有对应的硬链接的,只不过他是在我们node_modules里边给你建立了一个软链接,那么你真实的文件到底在哪里呢?其实是在.pnpm这个文件里边的
8、pnpm的存储store
在pnpm7.0之前,统一的存储位置是 ~/.pnpm-score中的;
在pnpm7.0之后,统一的存储位置进行了更改:/store
- 在 Linux 上,默认是 ~/.local/share/pnpm/store
- 在 Windows 上: %LOCALAPPDATA%/pnpm/store
- 在 macOS 上: ~/Library/pnpm/store
为什么要做出这样的改变不能跨磁盘建立硬链接的。
**我们可以通过一些终端命令获取这个目录:**获取当前活跃的store目录
sh
pnpm store path
**另外一个非常重要的store命令是prune(修剪):**从store中删除当前未被引用的包来释放store的空间
sh
pnpm store prune