pnpm使用体验

473 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第4天,点击查看活动详情

什么是pmpm

pnpm官网介绍:快速的,节省磁盘空间的包管理工具。pnpm官网

pnpm特点

  • 更快
  • 更小的磁盘占用
  • 软连接,硬链接
  • 重复的依赖项不会额外占用空间

image.png 图片来源pnpm官网

pnpm vs npm、yarn的区别

下图为pnpm官网给出的pnpm、npm、yarn、yarn PnP在不同场景安装速度的对比。

image.png 性能对比图片来源pnpm官网

从图片可以看出。pnpm在除update的场景。其余场景时间均快于其他几个包管理工具。尤其实在手机安装的时候。时间差异明显。

npm、yarn的痛点

  • 幽灵依赖(项目中使用了没有被定义在package.josn中的依赖)
  • 多个依赖间版本不同

在包管理工具发展的历史中。持续存在以下几个痛点。

  • 如何快速获取依赖包
  • 如何快速下载依赖包
  • 如何快速把依赖包写入硬盘

在npm@3版本后。加入了扁平化node_modules。根据依赖包引入的先后顺序。把依赖包扁平安装在node_modules目录下。遇到相同依赖包,不同依赖版本的情况。则会将后续不同版本的依赖包。维持嵌套的形式。安装在对应包的node_modules下面。

那么pnpm是怎么处理的呢?

pnpm原理

  1. 使用pnpm安装依赖后。会在node_modules下面生成一个.pnpm的文件。
  2. 在.pnpm内会将所有的依赖性包括相同依赖包的不同版本。全部放在.pmpm/node_modules下面。
  3. 如下node_modules根目录下的foo与.pnpm/foo@1.0.0下的bar都是通过软连接的方式。指向foo。
node_modules
├── foo -> ./.pnpm/foo@1.0.0/node_modules/foo
└── .pnpm
    ├── bar@1.0.0
    │   └── node_modules
    │       └── bar -> <store>/bar
    └── foo@1.0.0
        └── node_modules
            ├── foo -> <store>/foo
            └── bar -> ../../bar@1.0.0/node_modules/bar

遇到peer,则会为每一个不同的peer创建不同的依赖组。如下所示。

node_modules
└── .pnpm
    ├── foo@1.0.0_bar@1.0.0+baz@1.0.0
    │   └── node_modules
    │       ├── foo
    │       ├── bar   -> ../../bar@1.0.0/node_modules/bar
    │       ├── baz   -> ../../baz@1.0.0/node_modules/baz
    │       ├── qux   -> ../../qux@1.0.0/node_modules/qux
    │       └── plugh -> ../../plugh@1.0.0/node_modules/plugh
    ├── foo@1.0.0_bar@1.0.0+baz@1.1.0
    │   └── node_modules
    │       ├── foo
    │       ├── bar   -> ../../bar@1.0.0/node_modules/bar
    │       ├── baz   -> ../../baz@1.1.0/node_modules/baz
    │       ├── qux   -> ../../qux@1.0.0/node_modules/qux
    │       └── plugh -> ../../plugh@1.0.0/node_modules/plugh
    ├── bar@1.0.0
    ├── baz@1.0.0
    ├── baz@1.1.0
    ├── qux@1.0.0
    ├── plugh@1.0.0

pnpm在项目中的使用

使用下列命令可以直接创建一个pnpm、vue3、ts的项目。在项目中体验pnpm。

pnpm create vite my-vue-app --template vue-ts

pnpm的缺点

  • 没有独立的node_modules。调试某一包。可能会造成全局污染。
  • 软连接的创建也需要消耗磁盘空间。

如何将pnpm改为和npm、yarn相同的node_modules结构

在项目根目录创建文件.npmrc 文件内写入 node-linker=hoisted

删除现有的node_modules。重新pnpm install。

安装完成之后,查看node_modules目录就能发现。和之前的npm安装一样的目录结构。