pnpm 的介绍,安装与使用

为什么要使用 pnpm

当我们使用 npm 或 yarn 来安装项目依赖,如果我们的电脑里有很多的项目依赖了同个包,比如 axios,那么 axios 的包文件就会在电脑上存在多份,造成硬盘空间的浪费。使用 pnpm 则可以有效解决这一问题,因为所有的依赖包,都会存放在硬盘上的某一位置(pnpm-store),同一依赖包只会有一份文件,即使版本不同,也只会将不同版本间有差异的文件更新进存储库。当多个项目需要依赖某个包时,只需要创建到包文件的硬链接即可,而不需要重复地复制包。

那么什么是硬链接呢?

硬链接

硬链接(hard link)就是存储在硬盘里的一个文件的一个或多个文件名。在 Windows 电脑中,可以通过命令 mklink /H 创建硬链接后生成的文件 源文件 来实现创建硬链接,比如要通过 a.js 创建 b.js:

powershell 复制代码
mklink /H b.js a.js

执行结果如下:

当修改了 a.js 或 b.js,本质上都是修改了硬盘里的文件数据,所以一个文件修改了,另一个文件也会被修改。删除了 a.js,并不会影响 b.js 的访问,因为硬盘里的文件数据还在,只有当所有的硬链接都被删除了,硬盘里的文件数据才会被真正删除。图示如下:

软链接

既然有硬链接,那么相对应的,就有软链接(soft link)又叫符号链接(symbolic link),这个文件包含了另一个文件的路径名(绝对路径或相对路径)。在 Windows 电脑中,可以通过命令 mklink 创建软链接后生成的文件 源文件 来实现创建软链接,比如要通过 a.js 创建 c.js:

powershell 复制代码
mklink c.js a.js

执行结果如下:

图示如下:

创建后的 c.js 在 vs code 中显示时,可以看到右边有个 ,表明这是一个软链接:

如果直接去文件夹里查看,可以看到 c.js 有个快捷方式的图标,并且指向的目标为 a.js:

修改 c.js 的内容,实际上是通过软链接找到 a.js 再通过硬链接找到硬盘里的数据进行修改。如果删除了 a.js,那么 c.js 也就失效了。

pnpm 的安装与使用

说完硬链接和软链接的概念,我们来看看 pnpm 到底是如何使用的。首先是安装:

powershell 复制代码
npm install -g pnpm

注意最新的 pnpm 8 需要的 node 版本至少是 16:

在项目中使用时,也需要像 npm 那样先 init 创建 package.json 文件,但用不着跟上 -y 来表示默认配置初始化项目:

powershell 复制代码
pnpm init

安装包时使用的命令是 add,比如要安装 axios:

powershell 复制代码
pnpm add axios

安装成功后显示的信息比较多,如下图:

下面对其中一些信息做下说明:

  • "Content-addressable store is at: D:.pnpm-store\v3" 表明默认的 pnpm 的存储仓库的地址,实际上是在 D:.pnpm-store\v3,它们都是一些指向存储在硬盘中具体文件的硬链接:

我们也可以通过命令 pnpm store path 来查看 pnpm-store:

之所以在 D 盘,是因为我电脑上 D 盘是机械硬盘,项目都存放于此,C 盘为固态硬盘,而硬链接是无法跨磁盘的;

  • "reused 0" 表示这次安装复用了 0 个依赖(因为是首次使用 pnpm 下载 axios);
  • "downloaded 9" 表示下载了 9 个依赖;
  • "added 9" 表示往默认的 pnpm 的存储仓库中添加了 9 个依赖;
  • "resolved 9" 表示解析了 9 个依赖,如果是使用 npm 安装的 axios,就可以清晰地看到这 9 个依赖了:

因为 npm 的 node_modules 目录是扁平的,即使我们只安装了 axios,但是 axios 本身又依赖 3 个包:

这 3 个包又有依赖其它包,依次类推,总共 9 个,都会被提升到 node_modules 的根目录。这会导致一个理论上的问题,就是我们可以在编写代码时引用到并没有在 package.json 的 dependencies 里声明的包,比如 import followRedirects from 'follow-redirects'。而 pnpm 的 node_modules 目录是非扁平的,就可以解决这个问题。

非扁平的 node_modules 目录

同样是只安装了 axios,pnpm 的 node_modules 目录如下:

可以看到 node_modules 根目录下能找到的只有 axios,这样就无法在我们的项目中通过诸如 import followRedirects from 'follow-redirects' 来引用其它包了。并且 axios 右边还有个 符号,说明这是个软链接,它链接到的是 .pnpm 下的 axios@1.4.0,"1.4.0 "为 axios 的版本号。

axios@1.4.0 目录下还有个 node_modules,所以 pnpm 的 node_modules 是非扁平的,里面除了 axios 是硬链接,其它 3 个包又是软链接,指向的是 .pnpm 根目录下的对应的目录:

其它命令

除了 pnpm add <pkg>,还有些其它常见的命令,列于下方,更多可参加官方文档

  • pnpm install,用于安装项目的所有依赖,后面是不跟上某个具体的包的;
  • pnpm remove <pkg>,用于卸载某个包;
  • pnpm run,运行脚本命令,如果脚本名不与已有的 pnpm 命令名字相同,还可以省略 run
  • pnpm store prune,从存储(pnpm-store)中删除未引用的包。

相关推荐
小鱼冻干几秒前
node.js 文件流-可读取流
前端·node.js
飘尘1 分钟前
面试官:如何实现大量任务执行的调度?
前端·javascript·面试
印第安老斑鸠啊2 分钟前
微前端框架MicroApp本地开发改造篇--vite适配
前端
osspeace4 分钟前
使用husky+commitizen+semantic-release实现项目的全自动版本管理和发布
前端·javascript
Epicurus5 分钟前
使用transform: translate时出现闪烁现象如何解决
前端·css
前端卧龙人6 分钟前
别再重复造轮子,VueUse让前端开发更简单、更高效
前端
前端卧龙人6 分钟前
前端埋点与监控的核心要点
前端
前端大雄6 分钟前
前端面试之各大厂真题算法解析
前端·javascript·面试
银之夏雪丶7 分钟前
Vue 3 vs Vue 2:深入解析从性能优化到源码层面的进化
前端·vue.js
前端日常开发8 分钟前
一篇文章带你搞懂NextTick 是宏任务还是微任务
前端